https://kodi.wiki/api.php?action=feedcontributions&user=Sarbes&feedformat=atomOfficial Kodi Wiki - User contributions [en]2024-03-29T02:36:45ZUser contributionsMediaWiki 1.39.6https://kodi.wiki/index.php?title=Skin_Optimizations&diff=244315Skin Optimizations2023-02-19T23:19:48Z<p>Sarbes: /* Misc improvements */</p>
<hr />
<div>{{mininav|[[Development]]|[[Skinning]]}}<br />
== Why to optimize skins ==<br />
While the PC the skin is written on might be fast enough to render the GUI at 4k/60fps, it might be too expensive to run on lower end hardware. This page will give examples how to optimize skins, focusing on GPU performance.<br />
<br />
In general, the two most important resources on the GPU are memory bandwidth and computing power. Different systems might show different bottlenecks to render the GUI, but the following topics should help both.<br />
<br />
== Analysis via Renderdoc ==<br />
It is highly advised to use a tool like Renderdoc, a debugging program for computer graphics. While it offers a lot of features for graphics developers, it is also suitable for skinners to check for issues in the GUI layer compositing. With Renderdoc, the amount of overdraw can easily be judged.<br />
<br />
A tutorial how it can aid in skin development can be found [[Debugging_via_Renderdoc|here]].<br />
<br />
== Overdraw ==<br />
<br />
An important metric for performance evaluation is the amount of overdraw. Overdraw defines how many times a pixel gets rendered to, averaging across the whole screen. Using lots of layers increases the rendering costs. In order to have a performance target, a value should be picked when designing the skin. <br />
<br />
{| class="wikitable"<br />
|+ Typical overdraw values<br />
|-<br />
! Performance target !! Permissible Overdraw<br />
|-<br />
| Raspberry Pi 3, 1080p60 || 2.5<br />
|-<br />
| Raspberry Pi 4, 1080p60 || 3<br />
|-<br />
| Odroid C2, 1080p60 || 4.5<br />
|-<br />
| Intel HD 610, 1080p60 || 7<br />
|-<br />
| Intel HD 630, 2160p60 || 2.5<br />
|}<br />
<br />
Please take all of the values with a great pinch of salt. The actual value might vary when the system is busy, like when playing a video or rendering a visualization. Overdraw should be seen as a guide to keep the whole GUI experience consistent.<br />
<br />
Also, the performance target can be set lower when doing animations transitioning between menus. This will result in stutter on low-end systems during the transition, but the user experience is fine otherwise. On systems where the video is rendered via the GPU (Intel and similar "desktop" systems), this might be more noticable.<br />
<br />
As an example, a target of 3.5 permits the usage of one background layer (fanart) with one texture filter on top, while still leaving 1.5 pixel draws for UI elements.<br />
<br />
For comparison, the overdraw for the Estuary movie home screen is about 4.2, while the amount for Confluence is about 1.8.<br />
<br />
== Reducing layer counts ==<br />
<br />
While Kodi can render dozens of layers on top of each other, each layer consumes quite a bit of rendering resources. The overall goal should be to use as few layers as possible. <br />
<br />
Typically, the most performance gains can be made by reducing the full-screen layers, but this is not exclusive to them.<br />
<br />
=== Diffuse texture usage ===<br />
The skinning engine has the ability to apply diffuse textures. While it might be tempting to get the same effect via a separate texture, it is faster. <br />
<br />
[[Texture_Attributes|See here for additional information.]]<br />
=== Coloring via diffusecolors ===<br />
In a lot of skins, coloring/shading is done by applying a white, featureless texture with a diffuse color to do color filtering. Most often, the same/similar effect can be obtained by applying the diffuse color to the underlying layer, so a whole layer can be saved.<br />
<br />
With Kodi 20 (Nexus), it will even be possible to animate the diffuse color (see https://github.com/xbmc/xbmc/pull/21400).<br />
<br />
=== Squashing filter layers ===<br />
In a lot of skins, various shadow effects get applied to the fanart in the background. Most often, such effects can be combined together into one texture to achieve a very similar effect. <br />
<br />
Combined into a diffuse texture, such savings could halve the rendering cost for some skins.<br />
<br />
=== Disabling invisible layers ===<br />
Always disable occluded layers. Even though they have no impact on the final result, they still have to be processed and rendered. This wastes a lot of resources.<br />
<br />
=== Avoid presenting assets multiple times ===<br />
Another pitfall is to present an asset (posters, fanart, ...) multiple times in the exact same location. While this has no or just a small impact on the output, it eats up resources.<br />
<br />
=== Usage of background color ===<br />
If the skin uses a plain background color, set it via the <code><backgroundcolor></code> tag instead of using an image spanning the whole screen. This saves a good amount of resources.<br />
<br />
[[Skinning_Manual#Window_Header|See here for additional information.]]<br />
<br />
== Misc improvements ==<br />
Other optimization considerations.<br />
<br />
=== Proper asset sizes ===<br />
One easy to solve issue is the use of too large assets. Check the resolution of the displayed icons. They should be suitably sized to the targeted rendering resolution (most often 1920x1080). When too large, it will result in increased usage of memory resources and in '''decreased''' image quality.<br />
<br />
For a lot of background effects, a smaller resolution texture might be used. Often enough, just 1/4th of the target resolution might do the trick (e.g. 960x540), especially when there are multiple layers.<br />
<br />
=== Avoid infill by border textures ===<br />
If a <code>bordertexture</code> with a transparent center is used, the GUI can be informed via <code>infill="false"</code> that it does not have to be rendered.<br />
<br />
[[Image_Control#Available_tags_and_attributes|See here for additional information.]]<br />
<br />
=== Avoid almost opaque elements ===<br />
Consider using opaque elements instead of barely transparent ones. Especially on modern GPU's, this avoids rendering everything below such an element.<br />
<br />
=== Don't include unnecessary alpha layers in textures ===<br />
Including an alpha layer in a texture implies that it is used, even if the texture is fully opaque. The GUI has to treat such an element as transparent, with all the associated costs.<br />
<br />
=== Use single channel textures if possible ===<br />
A lot of GUI assets included in skins are delivered in a RGB format, even when they are greyscale. A single channel format saves disk space and might even reduce memory bandwidth in the future. Such textures can be colored by a <code>diffusecolor</code>.<br />
<br />
=== Don't use different uniformly colored textures ===<br />
Skins might use different textures to color in elements (for example "white.png", "red.png", "black.png"). Instead of using textures for each color, use a white texture in combination with a diffuse color. This saves resources.<br />
<br />
=== Avoid dead-zones around icons ===<br />
Icons are often used as decals, featuring transparent portions. Keep those transparent to a minimum to save resources, as the transparent pixels have to be rendered as well.<br />
<br />
[[Category:Skin_development]]</div>Sarbeshttps://kodi.wiki/index.php?title=Animating_your_skin&diff=242319Animating your skin2022-06-26T13:37:54Z<p>Sarbes: /* Examples */</p>
<hr />
<div>{{mininav|[[Development]]|[[Add-on development]]|[[Skinning]]}}<br />
<section begin="main content" /><br />
The Kodi skin engine has support for animations between control and window states. The animations are defined through use of the <animation> tag, which has a defined type and various attributes that specify the animation to be performed. All animations are additive – if two of them are in effect at the same time, their effects are added together. You may also have more than one animation of each type.<br />
<br />
== Window Animations ==<br />
There are two valid window animations – the animation to perform when the window is opened, and the animation to perform when the window is closed. They take the same format as the control animations. You can, however, have more than one animation performed for the WindowOpen or WindowClose animation.<br />
<br />
== Control Animations ==<br />
There are 6 valid control animations: WindowOpen, WindowClose, Visible, Hidden, Focus, and Unfocus. There is also a combination animation VisibleChange that constructs the Visible animation, then reverses it for the Hidden animation.<br />
<br />
== Format of Animation Tags ==<br />
The animation tag is formatted as follows for a single animation:<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="EFFECT" attributes>TYPE</animation><br />
</syntaxhighlight><br />
and as follows for multiple animations:<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation type="TYPE" condition="Window.IsActive(Home)" reversible="false"><br />
<effect type="EFFECT" other_attributes /><br />
...<br />
<effect type="EFFECT" other_attributes /><br />
</animation><br />
</syntaxhighlight><br />
<br />
=== Types ===<br />
The type can be one of the following:<br />
; WindowOpen <br />
: Performed once only when the window is opened. <br />
; WindowClose <br />
: Performed once only when the window is closed. No animation is performed when switching to fullscreen video, however. <br />
;Visible <br />
:Performed when the control becomes visible via its <visible> tag. <br />
; Hidden <br />
: Performed when the control becomes hidden via its <visible> tag. <br />
; Focus <br />
: Performed when the control gains focus. <br />
; Unfocus <br />
: Performed when the control loses focus.<br />
; Conditional <br />
: Performed when the control's condition attribute is filled. <br />
; VisibleChange <br />
: The same as the Visible type, except the reverse animation is auto-created for the Hidden type. Just saves having to have both animations if the animation is the same in both directions (ie just reversed)<br />
<br />
=== Attributes ===<br />
The attributes available are as follows. Note that all attributes, like tags, are case sensitive<br />
; effect <br />
: Specifies the effect to use. Currently “fade”, fadediffuse, “slide”, “rotate”, "rotatex", "rotatey", and “zoom” are supported.<br />
: fade - influences the opaqueness<br />
: fadediffuse - influences the opaqueness and color<br />
: rotatex - rotates a control around the X-Axis (horizontal)<br />
: rotatey - rotates a control around the Y-Axis (vertical)<br />
: rotate - rotates a control around the Z-Axis<br />
: slide - translates the control<br />
: zoom - magnifies/minifies the control<br />
; time : <br />
Specifies the length of time that the animation will run, in milliseconds. <br />
; delay <br />
: The time to delay the transistion before starting it, in milliseconds. <br />
; start <br />
: The start state of the control for this transistion. <br />
:* For fades, this is the opaqueness as a percentage (ie start="100" is fully opaque, start="0" is fully transparent). <br />
:* For diffuse fades, this is the color as a "AARRGGBB" (ie start="FFFF0000" is fully red opaque; start="7F00FF00" is green, half transparent). <br />
:* For slides, this is the relative coordinate offset to start the control at (ie start="50,60" will start the control off at 50 pixels to the right, and 60 pixels below it's normal viewing position). <br />
:* For rotates, this is the starting degree offset from the horizontal. (ie start="30" will start the control off on an angle of 30 degrees from the horizontal). <br />
:* For zooms, this is the starting size as a percentage. (ie start="50,60" will start the control at 50% of it's horizontal size and 60% of it's vertical size). <br />
:Note: With zooms you can also specify the coordinates and dimensions of the texture. (ie start="left,top,width,height").<br />
; end <br />
: The end state of the control for this transistion. Similar to the start state, except that the end state is always kept after the animation is finished, and until the control changes its state. <br />
; acceleration <br />
: Amount to accelerate or decelerate during a “slide”, “zoom” or “rotate” transistion. For deceleration, use a negative value. A value of -1 will cause the control to come to rest at its end coordinates. Defaults to 0. (Also see the tween attribute)<br />
; center <br />
: Center of the rotation or zoom to perform with a “rotate” or “zoom” transistion. This is the coordinates about which the rotation or zoom will take place. eg center="30,50” will mean that all points will revolve around (or zoom from) the (30,50) pixel location. You can set center="auto" to have Kodi automatically zoom from the center of the control.<br />
: Center shifts the rotational axis at the level, rotatex - center="y,z" coordinates, rotatey - center="x,z" coordinates, rotate - center="x,y" coordinates<br />
; condition<br />
: The conditions under which this animation should be performed. Defaults to being always performed. [[Conditional Visibility|See here for a list of valid conditionals.]]<br />
; reversible <br />
: If “false” the animation is not reversed if it is interrupted when it is finished. For instance a Visible animation will normally be reversed (instead of running the Hidden animation) if the control becomes hidden before the visible animation has finished. Setting reversible="false” prevents this behaviour (the Hidden animation will take its place). Defaults to true.<br />
; loop<br />
: If “true” will make your animation loop. (jump back to the start after it reaches the end)<br />
; pulse <br />
: If “true” will make your animation pulse. (Bounce back from start to end to start to end .........)<br />
; tween<br />
: Tween is like an advanced acceleration attribute that can be applied to all animations. Instead of a steady acceleration or deceleration, you can specify curves that the animation should follow. Currently, the engine supports “elastic“, “bounce“, “circle“, “back“, “sine“, “cubic“, “quadratic“ and, the default, “linear“. [[Tweeners|More information about Tweeners]]<br />
; easing<br />
: Easing basically defines the direction of the tween and can be one of “out“, “inout“ and “in“. The default value is “out“. [[Tweeners|More information about Easing]]<br />
<br />
== Examples ==<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<visible>Player.HasAudio</visible><br />
<animation effect="fade" time="400">VisibleChange</animation><br />
</syntaxhighlight><br />
<br />
This causes Kodi to fade the control in 400 milliseconds between the visible and hidden states. The control will start off hidden, and will fade in over 400ms when you play audio, and when it's finished, it will fade out again over 400ms.<br />
----<br />
You can also specify different transistion times for transistioning in and out as follows:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" time="100">WindowOpen</animation><br />
<animation effect="fade" time="1000">WindowClose</animation><br />
</syntaxhighlight><br />
<br />
<br />
This, when used as the animation tag for the ~MusicOSD dialog, will cause it to fade in quickly (in 100ms) when activated and the fade out again slowly (in 1 second (1000ms)) when it's cancelled.<br />
----<br />
You can also specify that a control should always fade in when the window is opened by using<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" time="200">WindowOpen</animation><br />
</syntaxhighlight><br />
<br />
This specifies that it will always start hidden, but will fade in immediately (over a time of 200ms) when the window is opened.<br />
<br />
----<br />
There is also ability to add delays preceding the transistions. For instance<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" time="200" delay="200">Hidden</animation><br />
</syntaxhighlight><br />
<br />
would mean that the control will fade out after a delay of 200ms. This is useful for "crossfade" effects, where you want the new control to fade in while the old control is still on screen (and then fade the old one out once the new one is completely opaque).<br />
----<br />
There are also slide effects available.<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="slide" end="30,0" time="200">Focus</animation><br />
</syntaxhighlight><br />
<br />
will slide the control 30 pixels to the right of its normal position when it becomes focused. Note that when it becomes unfocused it will jump back to it's normal position. A Unfocus animation will make it slide back gracefully.<br />
----<br />
There are also rotate effects available.<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="rotate" end="30" center="360,288" time="200">Focus</animation><br />
</syntaxhighlight><br />
<br />
will rotate the control 30 degrees counter clockwise about the center of a PAL screen (360,288) when the control becomes focused.<br />
----<br />
And we also have zoom effects.<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="zoom" end="120" center="360,288" time="200">Focus</animation><br />
</syntaxhighlight><br />
<br />
will zoom the control to 120% of its normal size when the control becomes focused, with the zoom centered at the center of a PAL screen (360,288). You can zoom each dimension by different amounts (effectively a stretch operation) as well. To stretch a control an extra 50% horizontally when focused, we can use<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="zoom" end="150,100" center="360,288" time="200">Focus</animation><br />
</syntaxhighlight><br />
----<br />
An example of a condition attribute is:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="slide" start="-120,0" time="200" condition="Window.Previous(Home)">WindowOpen</animation><br />
</syntaxhighlight><br />
<br />
This will cause the slide animation to only be performed if you are coming to this window from the Home window.<br />
----<br />
An example of a Conditional animation type is:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="slide" start="-120,0" time="200" condition="Control.HasFocus(2)">Conditional</animation><br />
</syntaxhighlight><br />
<br />
This will cause the slide animation to only be performed when the control with the id of 2 gains focus.<br />
----<br />
An example of a fade animation with a pulse:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" start="20" time="200" condition="Control.HasFocus(2)" pulse="true">Conditional</animation><br />
</syntaxhighlight><br />
<br />
This will cause the control to start at 20% opacity and fade to full in 200 milliseconds and fade back to 20% opacity and keeping looping in that fashion<br />
----<br />
An example of a fadediffuse animation with a pulse:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fadediffuse" start="FFFF0000" start="FF00FF00" time="200" condition="Control.HasFocus(2)" pulse="true">Conditional</animation><br />
</syntaxhighlight><br />
<br />
Similar to the example above, but it pulses between red and green.<br />
----<br />
An example of two animations at once:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation type="WindowOpen"><br />
<effect type="fade" start="0" end="100" time="200"/><br />
<effect type="zoom" end="150,100" center="auto" time="200" delay="200"/><br />
</animation><br />
</syntaxhighlight><br />
<br />
This will cause the control to fade in over 200 ms, then zoom to 150% it's width from the center of the control.<br />
<br />
<section end="main content" /><br />
<br />
== See also ==<br />
'''Development:'''<br />
* [[Add-on development]]<br />
* [[Skinning]]<br />
<br />
[[Category:Skin development]]</div>Sarbeshttps://kodi.wiki/index.php?title=Animating_your_skin&diff=242318Animating your skin2022-06-26T13:34:03Z<p>Sarbes: /* Attributes */</p>
<hr />
<div>{{mininav|[[Development]]|[[Add-on development]]|[[Skinning]]}}<br />
<section begin="main content" /><br />
The Kodi skin engine has support for animations between control and window states. The animations are defined through use of the <animation> tag, which has a defined type and various attributes that specify the animation to be performed. All animations are additive – if two of them are in effect at the same time, their effects are added together. You may also have more than one animation of each type.<br />
<br />
== Window Animations ==<br />
There are two valid window animations – the animation to perform when the window is opened, and the animation to perform when the window is closed. They take the same format as the control animations. You can, however, have more than one animation performed for the WindowOpen or WindowClose animation.<br />
<br />
== Control Animations ==<br />
There are 6 valid control animations: WindowOpen, WindowClose, Visible, Hidden, Focus, and Unfocus. There is also a combination animation VisibleChange that constructs the Visible animation, then reverses it for the Hidden animation.<br />
<br />
== Format of Animation Tags ==<br />
The animation tag is formatted as follows for a single animation:<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="EFFECT" attributes>TYPE</animation><br />
</syntaxhighlight><br />
and as follows for multiple animations:<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation type="TYPE" condition="Window.IsActive(Home)" reversible="false"><br />
<effect type="EFFECT" other_attributes /><br />
...<br />
<effect type="EFFECT" other_attributes /><br />
</animation><br />
</syntaxhighlight><br />
<br />
=== Types ===<br />
The type can be one of the following:<br />
; WindowOpen <br />
: Performed once only when the window is opened. <br />
; WindowClose <br />
: Performed once only when the window is closed. No animation is performed when switching to fullscreen video, however. <br />
;Visible <br />
:Performed when the control becomes visible via its <visible> tag. <br />
; Hidden <br />
: Performed when the control becomes hidden via its <visible> tag. <br />
; Focus <br />
: Performed when the control gains focus. <br />
; Unfocus <br />
: Performed when the control loses focus.<br />
; Conditional <br />
: Performed when the control's condition attribute is filled. <br />
; VisibleChange <br />
: The same as the Visible type, except the reverse animation is auto-created for the Hidden type. Just saves having to have both animations if the animation is the same in both directions (ie just reversed)<br />
<br />
=== Attributes ===<br />
The attributes available are as follows. Note that all attributes, like tags, are case sensitive<br />
; effect <br />
: Specifies the effect to use. Currently “fade”, fadediffuse, “slide”, “rotate”, "rotatex", "rotatey", and “zoom” are supported.<br />
: fade - influences the opaqueness<br />
: fadediffuse - influences the opaqueness and color<br />
: rotatex - rotates a control around the X-Axis (horizontal)<br />
: rotatey - rotates a control around the Y-Axis (vertical)<br />
: rotate - rotates a control around the Z-Axis<br />
: slide - translates the control<br />
: zoom - magnifies/minifies the control<br />
; time : <br />
Specifies the length of time that the animation will run, in milliseconds. <br />
; delay <br />
: The time to delay the transistion before starting it, in milliseconds. <br />
; start <br />
: The start state of the control for this transistion. <br />
:* For fades, this is the opaqueness as a percentage (ie start="100" is fully opaque, start="0" is fully transparent). <br />
:* For diffuse fades, this is the color as a "AARRGGBB" (ie start="FFFF0000" is fully red opaque; start="7F00FF00" is green, half transparent). <br />
:* For slides, this is the relative coordinate offset to start the control at (ie start="50,60" will start the control off at 50 pixels to the right, and 60 pixels below it's normal viewing position). <br />
:* For rotates, this is the starting degree offset from the horizontal. (ie start="30" will start the control off on an angle of 30 degrees from the horizontal). <br />
:* For zooms, this is the starting size as a percentage. (ie start="50,60" will start the control at 50% of it's horizontal size and 60% of it's vertical size). <br />
:Note: With zooms you can also specify the coordinates and dimensions of the texture. (ie start="left,top,width,height").<br />
; end <br />
: The end state of the control for this transistion. Similar to the start state, except that the end state is always kept after the animation is finished, and until the control changes its state. <br />
; acceleration <br />
: Amount to accelerate or decelerate during a “slide”, “zoom” or “rotate” transistion. For deceleration, use a negative value. A value of -1 will cause the control to come to rest at its end coordinates. Defaults to 0. (Also see the tween attribute)<br />
; center <br />
: Center of the rotation or zoom to perform with a “rotate” or “zoom” transistion. This is the coordinates about which the rotation or zoom will take place. eg center="30,50” will mean that all points will revolve around (or zoom from) the (30,50) pixel location. You can set center="auto" to have Kodi automatically zoom from the center of the control.<br />
: Center shifts the rotational axis at the level, rotatex - center="y,z" coordinates, rotatey - center="x,z" coordinates, rotate - center="x,y" coordinates<br />
; condition<br />
: The conditions under which this animation should be performed. Defaults to being always performed. [[Conditional Visibility|See here for a list of valid conditionals.]]<br />
; reversible <br />
: If “false” the animation is not reversed if it is interrupted when it is finished. For instance a Visible animation will normally be reversed (instead of running the Hidden animation) if the control becomes hidden before the visible animation has finished. Setting reversible="false” prevents this behaviour (the Hidden animation will take its place). Defaults to true.<br />
; loop<br />
: If “true” will make your animation loop. (jump back to the start after it reaches the end)<br />
; pulse <br />
: If “true” will make your animation pulse. (Bounce back from start to end to start to end .........)<br />
; tween<br />
: Tween is like an advanced acceleration attribute that can be applied to all animations. Instead of a steady acceleration or deceleration, you can specify curves that the animation should follow. Currently, the engine supports “elastic“, “bounce“, “circle“, “back“, “sine“, “cubic“, “quadratic“ and, the default, “linear“. [[Tweeners|More information about Tweeners]]<br />
; easing<br />
: Easing basically defines the direction of the tween and can be one of “out“, “inout“ and “in“. The default value is “out“. [[Tweeners|More information about Easing]]<br />
<br />
== Examples ==<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<visible>Player.HasAudio</visible><br />
<animation effect="fade" time="400">VisibleChange</animation><br />
</syntaxhighlight><br />
<br />
This causes Kodi to fade the control in 400 milliseconds between the visible and hidden states. The control will start off hidden, and will fade in over 400ms when you play audio, and when it's finished, it will fade out again over 400ms.<br />
----<br />
You can also specify different transistion times for transistioning in and out as follows:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" time="100">WindowOpen</animation><br />
<animation effect="fade" time="1000">WindowClose</animation><br />
</syntaxhighlight><br />
<br />
<br />
This, when used as the animation tag for the ~MusicOSD dialog, will cause it to fade in quickly (in 100ms) when activated and the fade out again slowly (in 1 second (1000ms)) when it's cancelled.<br />
----<br />
You can also specify that a control should always fade in when the window is opened by using<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" time="200">WindowOpen</animation><br />
</syntaxhighlight><br />
<br />
This specifies that it will always start hidden, but will fade in immediately (over a time of 200ms) when the window is opened.<br />
<br />
----<br />
There is also ability to add delays preceding the transistions. For instance<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" time="200" delay="200">Hidden</animation><br />
</syntaxhighlight><br />
<br />
would mean that the control will fade out after a delay of 200ms. This is useful for "crossfade" effects, where you want the new control to fade in while the old control is still on screen (and then fade the old one out once the new one is completely opaque).<br />
----<br />
There are also slide effects available.<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="slide" end="30,0" time="200">Focus</animation><br />
</syntaxhighlight><br />
<br />
will slide the control 30 pixels to the right of its normal position when it becomes focused. Note that when it becomes unfocused it will jump back to it's normal position. A Unfocus animation will make it slide back gracefully.<br />
----<br />
There are also rotate effects available.<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="rotate" end="30" center="360,288" time="200">Focus</animation><br />
</syntaxhighlight><br />
<br />
will rotate the control 30 degrees counter clockwise about the center of a PAL screen (360,288) when the control becomes focused.<br />
----<br />
And we also have zoom effects.<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="zoom" end="120" center="360,288" time="200">Focus</animation><br />
</syntaxhighlight><br />
<br />
will zoom the control to 120% of its normal size when the control becomes focused, with the zoom centered at the center of a PAL screen (360,288). You can zoom each dimension by different amounts (effectively a stretch operation) as well. To stretch a control an extra 50% horizontally when focused, we can use<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="zoom" end="150,100" center="360,288" time="200">Focus</animation><br />
</syntaxhighlight><br />
----<br />
An example of a condition attribute is:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="slide" start="-120,0" time="200" condition="Window.Previous(Home)">WindowOpen</animation><br />
</syntaxhighlight><br />
<br />
This will cause the slide animation to only be performed if you are coming to this window from the Home window.<br />
----<br />
An example of a Conditional animation type is:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="slide" start="-120,0" time="200" condition="Control.HasFocus(2)">Conditional</animation><br />
</syntaxhighlight><br />
<br />
This will cause the slide animation to only be performed when the control with the id of 2 gains focus.<br />
----<br />
An example of a fade animation with a pulse:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" start="20" time="200" condition="Control.HasFocus(2)" pulse="true">Conditional</animation><br />
</syntaxhighlight><br />
<br />
This will cause the control to start at 20% opacity and fade to full in 200 milliseconds and fade back to 20% opacity and keeping looping in that fashion<br />
----<br />
An example of two animations at once:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation type="WindowOpen"><br />
<effect type="fade" start="0" end="100" time="200"/><br />
<effect type="zoom" end="150,100" center="auto" time="200" delay="200"/><br />
</animation><br />
</syntaxhighlight><br />
<br />
This will cause the control to fade in over 200 ms, then zoom to 150% it's width from the center of the control.<br />
<br />
<section end="main content" /><br />
== See also ==<br />
'''Development:'''<br />
* [[Add-on development]]<br />
* [[Skinning]]<br />
<br />
[[Category:Skin development]]</div>Sarbeshttps://kodi.wiki/index.php?title=Animating_your_skin&diff=242317Animating your skin2022-06-26T13:29:56Z<p>Sarbes: /* Attributes */</p>
<hr />
<div>{{mininav|[[Development]]|[[Add-on development]]|[[Skinning]]}}<br />
<section begin="main content" /><br />
The Kodi skin engine has support for animations between control and window states. The animations are defined through use of the <animation> tag, which has a defined type and various attributes that specify the animation to be performed. All animations are additive – if two of them are in effect at the same time, their effects are added together. You may also have more than one animation of each type.<br />
<br />
== Window Animations ==<br />
There are two valid window animations – the animation to perform when the window is opened, and the animation to perform when the window is closed. They take the same format as the control animations. You can, however, have more than one animation performed for the WindowOpen or WindowClose animation.<br />
<br />
== Control Animations ==<br />
There are 6 valid control animations: WindowOpen, WindowClose, Visible, Hidden, Focus, and Unfocus. There is also a combination animation VisibleChange that constructs the Visible animation, then reverses it for the Hidden animation.<br />
<br />
== Format of Animation Tags ==<br />
The animation tag is formatted as follows for a single animation:<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="EFFECT" attributes>TYPE</animation><br />
</syntaxhighlight><br />
and as follows for multiple animations:<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation type="TYPE" condition="Window.IsActive(Home)" reversible="false"><br />
<effect type="EFFECT" other_attributes /><br />
...<br />
<effect type="EFFECT" other_attributes /><br />
</animation><br />
</syntaxhighlight><br />
<br />
=== Types ===<br />
The type can be one of the following:<br />
; WindowOpen <br />
: Performed once only when the window is opened. <br />
; WindowClose <br />
: Performed once only when the window is closed. No animation is performed when switching to fullscreen video, however. <br />
;Visible <br />
:Performed when the control becomes visible via its <visible> tag. <br />
; Hidden <br />
: Performed when the control becomes hidden via its <visible> tag. <br />
; Focus <br />
: Performed when the control gains focus. <br />
; Unfocus <br />
: Performed when the control loses focus.<br />
; Conditional <br />
: Performed when the control's condition attribute is filled. <br />
; VisibleChange <br />
: The same as the Visible type, except the reverse animation is auto-created for the Hidden type. Just saves having to have both animations if the animation is the same in both directions (ie just reversed)<br />
<br />
=== Attributes ===<br />
The attributes available are as follows. Note that all attributes, like tags, are case sensitive<br />
; effect <br />
: Specifies the effect to use. Currently “fade”, fadediffuse, “slide”, “rotate”, "rotatex", "rotatey", and “zoom” are supported.<br />
: rotatex - rotates a control around the X-Axis (horizontal)<br />
: rotatey - rotates a control around the Y-Axis (vertical)<br />
: rotate - rotates a control around the Z-Axis<br />
; time : <br />
Specifies the length of time that the animation will run, in milliseconds. <br />
; delay <br />
: The time to delay the transistion before starting it, in milliseconds. <br />
; start <br />
: The start state of the control for this transistion. <br />
:* For fades, this is the opaqueness as a percentage (ie start="100" is fully opaque, start="0" is fully transparent). <br />
:* For diffuse fades, this is the color as a "AARRGGBB" (ie start="FFFF0000" is fully red opaque; start="7F00FF00" is green, half transparent). <br />
:* For slides, this is the relative coordinate offset to start the control at (ie start="50,60" will start the control off at 50 pixels to the right, and 60 pixels below it's normal viewing position). <br />
:* For rotates, this is the starting degree offset from the horizontal. (ie start="30" will start the control off on an angle of 30 degrees from the horizontal). <br />
:* For zooms, this is the starting size as a percentage. (ie start="50,60" will start the control at 50% of it's horizontal size and 60% of it's vertical size). <br />
:Note: With zooms you can also specify the coordinates and dimensions of the texture. (ie start="left,top,width,height").<br />
; end <br />
: The end state of the control for this transistion. Similar to the start state, except that the end state is always kept after the animation is finished, and until the control changes its state. <br />
; acceleration <br />
: Amount to accelerate or decelerate during a “slide”, “zoom” or “rotate” transistion. For deceleration, use a negative value. A value of -1 will cause the control to come to rest at its end coordinates. Defaults to 0. (Also see the tween attribute)<br />
; center <br />
: Center of the rotation or zoom to perform with a “rotate” or “zoom” transistion. This is the coordinates about which the rotation or zoom will take place. eg center="30,50” will mean that all points will revolve around (or zoom from) the (30,50) pixel location. You can set center="auto" to have Kodi automatically zoom from the center of the control.<br />
: Center shifts the rotational axis at the level, rotatex - center="y,z" coordinates, rotatey - center="x,z" coordinates, rotate - center="x,y" coordinates<br />
; condition<br />
: The conditions under which this animation should be performed. Defaults to being always performed. [[Conditional Visibility|See here for a list of valid conditionals.]]<br />
; reversible <br />
: If “false” the animation is not reversed if it is interrupted when it is finished. For instance a Visible animation will normally be reversed (instead of running the Hidden animation) if the control becomes hidden before the visible animation has finished. Setting reversible="false” prevents this behaviour (the Hidden animation will take its place). Defaults to true.<br />
; loop<br />
: If “true” will make your animation loop. (jump back to the start after it reaches the end)<br />
; pulse <br />
: If “true” will make your animation pulse. (Bounce back from start to end to start to end .........)<br />
; tween<br />
: Tween is like an advanced acceleration attribute that can be applied to all animations. Instead of a steady acceleration or deceleration, you can specify curves that the animation should follow. Currently, the engine supports “elastic“, “bounce“, “circle“, “back“, “sine“, “cubic“, “quadratic“ and, the default, “linear“. [[Tweeners|More information about Tweeners]]<br />
; easing<br />
: Easing basically defines the direction of the tween and can be one of “out“, “inout“ and “in“. The default value is “out“. [[Tweeners|More information about Easing]]<br />
<br />
== Examples ==<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<visible>Player.HasAudio</visible><br />
<animation effect="fade" time="400">VisibleChange</animation><br />
</syntaxhighlight><br />
<br />
This causes Kodi to fade the control in 400 milliseconds between the visible and hidden states. The control will start off hidden, and will fade in over 400ms when you play audio, and when it's finished, it will fade out again over 400ms.<br />
----<br />
You can also specify different transistion times for transistioning in and out as follows:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" time="100">WindowOpen</animation><br />
<animation effect="fade" time="1000">WindowClose</animation><br />
</syntaxhighlight><br />
<br />
<br />
This, when used as the animation tag for the ~MusicOSD dialog, will cause it to fade in quickly (in 100ms) when activated and the fade out again slowly (in 1 second (1000ms)) when it's cancelled.<br />
----<br />
You can also specify that a control should always fade in when the window is opened by using<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" time="200">WindowOpen</animation><br />
</syntaxhighlight><br />
<br />
This specifies that it will always start hidden, but will fade in immediately (over a time of 200ms) when the window is opened.<br />
<br />
----<br />
There is also ability to add delays preceding the transistions. For instance<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" time="200" delay="200">Hidden</animation><br />
</syntaxhighlight><br />
<br />
would mean that the control will fade out after a delay of 200ms. This is useful for "crossfade" effects, where you want the new control to fade in while the old control is still on screen (and then fade the old one out once the new one is completely opaque).<br />
----<br />
There are also slide effects available.<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="slide" end="30,0" time="200">Focus</animation><br />
</syntaxhighlight><br />
<br />
will slide the control 30 pixels to the right of its normal position when it becomes focused. Note that when it becomes unfocused it will jump back to it's normal position. A Unfocus animation will make it slide back gracefully.<br />
----<br />
There are also rotate effects available.<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="rotate" end="30" center="360,288" time="200">Focus</animation><br />
</syntaxhighlight><br />
<br />
will rotate the control 30 degrees counter clockwise about the center of a PAL screen (360,288) when the control becomes focused.<br />
----<br />
And we also have zoom effects.<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="zoom" end="120" center="360,288" time="200">Focus</animation><br />
</syntaxhighlight><br />
<br />
will zoom the control to 120% of its normal size when the control becomes focused, with the zoom centered at the center of a PAL screen (360,288). You can zoom each dimension by different amounts (effectively a stretch operation) as well. To stretch a control an extra 50% horizontally when focused, we can use<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="zoom" end="150,100" center="360,288" time="200">Focus</animation><br />
</syntaxhighlight><br />
----<br />
An example of a condition attribute is:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="slide" start="-120,0" time="200" condition="Window.Previous(Home)">WindowOpen</animation><br />
</syntaxhighlight><br />
<br />
This will cause the slide animation to only be performed if you are coming to this window from the Home window.<br />
----<br />
An example of a Conditional animation type is:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="slide" start="-120,0" time="200" condition="Control.HasFocus(2)">Conditional</animation><br />
</syntaxhighlight><br />
<br />
This will cause the slide animation to only be performed when the control with the id of 2 gains focus.<br />
----<br />
An example of a fade animation with a pulse:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation effect="fade" start="20" time="200" condition="Control.HasFocus(2)" pulse="true">Conditional</animation><br />
</syntaxhighlight><br />
<br />
This will cause the control to start at 20% opacity and fade to full in 200 milliseconds and fade back to 20% opacity and keeping looping in that fashion<br />
----<br />
An example of two animations at once:<br />
<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<animation type="WindowOpen"><br />
<effect type="fade" start="0" end="100" time="200"/><br />
<effect type="zoom" end="150,100" center="auto" time="200" delay="200"/><br />
</animation><br />
</syntaxhighlight><br />
<br />
This will cause the control to fade in over 200 ms, then zoom to 150% it's width from the center of the control.<br />
<br />
<section end="main content" /><br />
== See also ==<br />
'''Development:'''<br />
* [[Add-on development]]<br />
* [[Skinning]]<br />
<br />
[[Category:Skin development]]</div>Sarbeshttps://kodi.wiki/index.php?title=Skin_Optimizations&diff=242230Skin Optimizations2022-06-09T14:49:12Z<p>Sarbes: /* Overdraw */</p>
<hr />
<div>{{mininav|[[Development]]|[[Skinning]]}}<br />
== Why to optimize skins ==<br />
While the PC the skin is written on might be fast enough to render the GUI at 4k/60fps, it might be too expensive to run on lower end hardware. This page will give examples how to optimize skins, focusing on GPU performance.<br />
<br />
In general, the two most important resources on the GPU are memory bandwidth and computing power. Different systems might show different bottlenecks to render the GUI, but the following topics should help both.<br />
<br />
== Analysis via Renderdoc ==<br />
It is highly advised to use a tool like Renderdoc, a debugging program for computer graphics. While it offers a lot of features for graphics developers, it is also suitable for skinners to check for issues in the GUI layer compositing. With Renderdoc, the amount of overdraw can easily be judged.<br />
<br />
A tutorial how it can aid in skin development can be found [[Debugging_via_Renderdoc|here]].<br />
<br />
== Overdraw ==<br />
<br />
An important metric for performance evaluation is the amount of overdraw. Overdraw defines how many times a pixel gets rendered to, averaging across the whole screen. Using lots of layers increases the rendering costs. In order to have a performance target, a value should be picked when designing the skin. <br />
<br />
{| class="wikitable"<br />
|+ Typical overdraw values<br />
|-<br />
! Performance target !! Permissible Overdraw<br />
|-<br />
| Raspberry Pi 3, 1080p60 || 2.5<br />
|-<br />
| Raspberry Pi 4, 1080p60 || 3<br />
|-<br />
| Odroid C2, 1080p60 || 4.5<br />
|-<br />
| Intel HD 610, 1080p60 || 7<br />
|-<br />
| Intel HD 630, 2160p60 || 2.5<br />
|}<br />
<br />
Please take all of the values with a great pinch of salt. The actual value might vary when the system is busy, like when playing a video or rendering a visualization. Overdraw should be seen as a guide to keep the whole GUI experience consistent.<br />
<br />
Also, the performance target can be set lower when doing animations transitioning between menus. This will result in stutter on low-end systems during the transition, but the user experience is fine otherwise. On systems where the video is rendered via the GPU (Intel and similar "desktop" systems), this might be more noticable.<br />
<br />
As an example, a target of 3.5 permits the usage of one background layer (fanart) with one texture filter on top, while still leaving 1.5 pixel draws for UI elements.<br />
<br />
For comparison, the overdraw for the Estuary movie home screen is about 4.2, while the amount for Confluence is about 1.8.<br />
<br />
== Reducing layer counts ==<br />
<br />
While Kodi can render dozens of layers on top of each other, each layer consumes quite a bit of rendering resources. The overall goal should be to use as few layers as possible. <br />
<br />
Typically, the most performance gains can be made by reducing the full-screen layers, but this is not exclusive to them.<br />
<br />
=== Diffuse texture usage ===<br />
The skinning engine has the ability to apply diffuse textures. While it might be tempting to get the same effect via a separate texture, it is faster. <br />
<br />
[[Texture_Attributes|See here for additional information.]]<br />
=== Coloring via diffusecolors ===<br />
In a lot of skins, coloring/shading is done by applying a white, featureless texture with a diffuse color to do color filtering. Most often, the same/similar effect can be obtained by applying the diffuse color to the underlying layer, so a whole layer can be saved.<br />
<br />
With Kodi 20 (Nexus), it will even be possible to animate the diffuse color (see https://github.com/xbmc/xbmc/pull/21400).<br />
<br />
=== Squashing filter layers ===<br />
In a lot of skins, various shadow effects get applied to the fanart in the background. Most often, such effects can be combined together into one texture to achieve a very similar effect. <br />
<br />
Combined into a diffuse texture, such savings could halve the rendering cost for some skins.<br />
<br />
=== Disabling invisible layers ===<br />
Always disable occluded layers. Even though they have no impact on the final result, they still have to be processed and rendered. This wastes a lot of resources.<br />
<br />
=== Avoid presenting assets multiple times ===<br />
Another pitfall is to present an asset (posters, fanart, ...) multiple times in the exact same location. While this has no or just a small impact on the output, it eats up resources.<br />
<br />
=== Usage of background color ===<br />
If the skin uses a plain background color, set it via the <code><backgroundcolor></code> tag instead of using an image spanning the whole screen. This saves a good amount of resources.<br />
<br />
[[Skinning_Manual#Window_Header|See here for additional information.]]<br />
<br />
== Misc improvements ==<br />
Other optimization considerations.<br />
<br />
=== Proper asset sizes ===<br />
One easy to solve issue is the use of too large assets. Check the resolution of the displayed icons. They should be suitably sized to the targeted rendering resolution (most often 1920x1080). When too large, it will result in increased usage of memory resources and in '''decreased''' image quality.<br />
<br />
For a lot of background effects, a smaller resolution texture might be used. Often enough, just 1/4th of the target resolution might do the trick (e.g. 960x540), especially when there are multiple layers.<br />
<br />
=== Avoid infill by border textures ===<br />
If a <code>bordertexture</code> with a transparent center is used, the GUI can be informed via <code>infill="false"</code> that it does not have to be rendered.<br />
<br />
[[Image_Control#Available_tags_and_attributes|See here for additional information.]]<br />
<br />
=== Avoid almost opaque elements ===<br />
Consider using opaque elements instead of barely transparent ones. Especially on modern GPU's, this avoids rendering everything below such an element.<br />
<br />
=== Don't include unnecessary alpha layers in textures ===<br />
Including an alpha layer in a texture implies that it is used, even if the texture is fully opaque. The GUI has to treat such an element as transparent, with all the associated costs.<br />
<br />
=== Use single channel textures if possible ===<br />
A lot of GUI assets included in skins are delivered in a RGB format, even when they are greyscale. A single channel format saves disk space and might even reduce memory bandwidth in the future. Such textures can be colored by a <code>diffusecolor</code>.<br />
<br />
[[Category:Skin_development]]</div>Sarbeshttps://kodi.wiki/index.php?title=Skin_Optimizations&diff=242229Skin Optimizations2022-06-09T14:47:48Z<p>Sarbes: /* Reducing layer counts */</p>
<hr />
<div>{{mininav|[[Development]]|[[Skinning]]}}<br />
== Why to optimize skins ==<br />
While the PC the skin is written on might be fast enough to render the GUI at 4k/60fps, it might be too expensive to run on lower end hardware. This page will give examples how to optimize skins, focusing on GPU performance.<br />
<br />
In general, the two most important resources on the GPU are memory bandwidth and computing power. Different systems might show different bottlenecks to render the GUI, but the following topics should help both.<br />
<br />
== Analysis via Renderdoc ==<br />
It is highly advised to use a tool like Renderdoc, a debugging program for computer graphics. While it offers a lot of features for graphics developers, it is also suitable for skinners to check for issues in the GUI layer compositing. With Renderdoc, the amount of overdraw can easily be judged.<br />
<br />
A tutorial how it can aid in skin development can be found [[Debugging_via_Renderdoc|here]].<br />
<br />
== Overdraw ==<br />
<br />
An important metric for performance evaluation is the amount of overdraw. Overdraw defines how many times a pixel gets rendered to, averaging across the whole screen. Using lots of layers increases the rendering costs. In order to have a performance target, a value should be picked when designing the skin. <br />
<br />
{| class="wikitable"<br />
|+ Typical overdraw values<br />
|-<br />
! Performance target !! Permissible Overdraw<br />
|-<br />
| Raspberry Pi 3, 1080p60 || 2.5<br />
|-<br />
| Raspberry Pi 4, 1080p60 || 3<br />
|-<br />
| Odroid C2, 1080p60 || 4.5<br />
|-<br />
| Intel HD 610, 1080p60 || 7<br />
|-<br />
| Intel HD 630, 2160p60 || 2.5<br />
|}<br />
<br />
Please take all of the values with a great pinch of salt. The actual value might vary when the system is busy, like when playing a video or rendering a visualization. Overdraw should be seen as a guide to keep the whole GUI experience consistent.<br />
<br />
Also, the performance target can be set lower when doing animations transitioning between menus. This will result in stutter on low-end systems during the transition, but the user experience is fine otherwise. On systems where the video is rendered via the GPU (Intel and similar "desktop" systems), this might be more noticable.<br />
<br />
As an example, a target of 3.5 permits the usage of one background layer (fanart) with one texture filter on top, while still leaving 1.5 pixel draws for UI elements.<br />
<br />
For comparison, the overdraw for The Estuary movie screen is about 4.2, while the amount for Confluence is about 1.8.<br />
<br />
== Reducing layer counts ==<br />
<br />
While Kodi can render dozens of layers on top of each other, each layer consumes quite a bit of rendering resources. The overall goal should be to use as few layers as possible. <br />
<br />
Typically, the most performance gains can be made by reducing the full-screen layers, but this is not exclusive to them.<br />
<br />
=== Diffuse texture usage ===<br />
The skinning engine has the ability to apply diffuse textures. While it might be tempting to get the same effect via a separate texture, it is faster. <br />
<br />
[[Texture_Attributes|See here for additional information.]]<br />
=== Coloring via diffusecolors ===<br />
In a lot of skins, coloring/shading is done by applying a white, featureless texture with a diffuse color to do color filtering. Most often, the same/similar effect can be obtained by applying the diffuse color to the underlying layer, so a whole layer can be saved.<br />
<br />
With Kodi 20 (Nexus), it will even be possible to animate the diffuse color (see https://github.com/xbmc/xbmc/pull/21400).<br />
<br />
=== Squashing filter layers ===<br />
In a lot of skins, various shadow effects get applied to the fanart in the background. Most often, such effects can be combined together into one texture to achieve a very similar effect. <br />
<br />
Combined into a diffuse texture, such savings could halve the rendering cost for some skins.<br />
<br />
=== Disabling invisible layers ===<br />
Always disable occluded layers. Even though they have no impact on the final result, they still have to be processed and rendered. This wastes a lot of resources.<br />
<br />
=== Avoid presenting assets multiple times ===<br />
Another pitfall is to present an asset (posters, fanart, ...) multiple times in the exact same location. While this has no or just a small impact on the output, it eats up resources.<br />
<br />
=== Usage of background color ===<br />
If the skin uses a plain background color, set it via the <code><backgroundcolor></code> tag instead of using an image spanning the whole screen. This saves a good amount of resources.<br />
<br />
[[Skinning_Manual#Window_Header|See here for additional information.]]<br />
<br />
== Misc improvements ==<br />
Other optimization considerations.<br />
<br />
=== Proper asset sizes ===<br />
One easy to solve issue is the use of too large assets. Check the resolution of the displayed icons. They should be suitably sized to the targeted rendering resolution (most often 1920x1080). When too large, it will result in increased usage of memory resources and in '''decreased''' image quality.<br />
<br />
For a lot of background effects, a smaller resolution texture might be used. Often enough, just 1/4th of the target resolution might do the trick (e.g. 960x540), especially when there are multiple layers.<br />
<br />
=== Avoid infill by border textures ===<br />
If a <code>bordertexture</code> with a transparent center is used, the GUI can be informed via <code>infill="false"</code> that it does not have to be rendered.<br />
<br />
[[Image_Control#Available_tags_and_attributes|See here for additional information.]]<br />
<br />
=== Avoid almost opaque elements ===<br />
Consider using opaque elements instead of barely transparent ones. Especially on modern GPU's, this avoids rendering everything below such an element.<br />
<br />
=== Don't include unnecessary alpha layers in textures ===<br />
Including an alpha layer in a texture implies that it is used, even if the texture is fully opaque. The GUI has to treat such an element as transparent, with all the associated costs.<br />
<br />
=== Use single channel textures if possible ===<br />
A lot of GUI assets included in skins are delivered in a RGB format, even when they are greyscale. A single channel format saves disk space and might even reduce memory bandwidth in the future. Such textures can be colored by a <code>diffusecolor</code>.<br />
<br />
[[Category:Skin_development]]</div>Sarbeshttps://kodi.wiki/index.php?title=Skin_Optimizations&diff=242228Skin Optimizations2022-06-08T07:45:59Z<p>Sarbes: /* Analysis via Renderdoc */</p>
<hr />
<div>{{mininav|[[Development]]|[[Skinning]]}}<br />
== Why to optimize skins ==<br />
While the PC the skin is written on might be fast enough to render the GUI at 4k/60fps, it might be too expensive to run on lower end hardware. This page will give examples how to optimize skins, focusing on GPU performance.<br />
<br />
In general, the two most important resources on the GPU are memory bandwidth and computing power. Different systems might show different bottlenecks to render the GUI, but the following topics should help both.<br />
<br />
== Analysis via Renderdoc ==<br />
It is highly advised to use a tool like Renderdoc, a debugging program for computer graphics. While it offers a lot of features for graphics developers, it is also suitable for skinners to check for issues in the GUI layer compositing. With Renderdoc, the amount of overdraw can easily be judged.<br />
<br />
A tutorial how it can aid in skin development can be found [[Debugging_via_Renderdoc|here]].<br />
<br />
== Overdraw ==<br />
<br />
An important metric for performance evaluation is the amount of overdraw. Overdraw defines how many times a pixel gets rendered to, averaging across the whole screen. Using lots of layers increases the rendering costs. In order to have a performance target, a value should be picked when designing the skin. <br />
<br />
{| class="wikitable"<br />
|+ Typical overdraw values<br />
|-<br />
! Performance target !! Permissible Overdraw<br />
|-<br />
| Raspberry Pi 3, 1080p60 || 2.5<br />
|-<br />
| Raspberry Pi 4, 1080p60 || 3<br />
|-<br />
| Odroid C2, 1080p60 || 4.5<br />
|-<br />
| Intel HD 610, 1080p60 || 7<br />
|-<br />
| Intel HD 630, 2160p60 || 2.5<br />
|}<br />
<br />
Please take all of the values with a great pinch of salt. The actual value might vary when the system is busy, like when playing a video or rendering a visualization. Overdraw should be seen as a guide to keep the whole GUI experience consistent.<br />
<br />
Also, the performance target can be set lower when doing animations transitioning between menus. This will result in stutter on low-end systems during the transition, but the user experience is fine otherwise. On systems where the video is rendered via the GPU (Intel and similar "desktop" systems), this might be more noticable.<br />
<br />
As an example, a target of 3.5 permits the usage of one background layer (fanart) with one texture filter on top, while still leaving 1.5 pixel draws for UI elements.<br />
<br />
For comparison, the overdraw for The Estuary movie screen is about 4.2, while the amount for Confluence is about 1.8.<br />
<br />
== Reducing layer counts ==<br />
<br />
While Kodi can render dozens of layers on top of each other, each layer consumes quite a bit of rendering resources. The overall goal should be to use as few layers as possible. <br />
<br />
Typically, the most performance gains can be made by reducing the full-screen layers, but this is not exclusive to them.<br />
<br />
=== Diffuse texture usage ===<br />
The skinning engine has the ability to apply diffuse textures. While it might be tempting to get the same effect via a separate texture, it is faster. <br />
<br />
[[Texture_Attributes|See here for additional information.]]<br />
=== Coloring via diffusecolors ===<br />
In a lot of skins, coloring/shading is done by applying a white, featureless texture with a diffuse color to do color filtering. Most often, the same/similar effect can be obtained by applying the diffuse color to the underlying layer, so a whole layer can be saved.<br />
<br />
With Kodi 20 (Nexus), it will even be possible to animate the diffuse color (see https://github.com/xbmc/xbmc/pull/21400).<br />
<br />
=== Squashing filter layers ===<br />
In a lot of skins, various shadow effects get applied to the fanart in the background. Most often, such effects can be combined together into one texture to achieve a very similar effect. <br />
<br />
Combined into a diffuse texture, such savings could halve the rendering cost for some skins.<br />
<br />
=== Disabling invisible layers ===<br />
Always disable occluded layers. Even though they have no impact on the final result, they still have to be processed and rendered. This wastes a lot of resources.<br />
<br />
=== Avoid presenting assets multiple times ===<br />
Another pitfall is to present an asset (posters, fanart, ...) multiple times in the exact same location. While this has no or just a small impact on the ouptut, it eats up resources.<br />
<br />
== Misc improvements ==<br />
Other optimization considerations.<br />
<br />
=== Proper asset sizes ===<br />
One easy to solve issue is the use of too large assets. Check the resolution of the displayed icons. They should be suitably sized to the targeted rendering resolution (most often 1920x1080). When too large, it will result in increased usage of memory resources and in '''decreased''' image quality.<br />
<br />
For a lot of background effects, a smaller resolution texture might be used. Often enough, just 1/4th of the target resolution might do the trick (e.g. 960x540), especially when there are multiple layers.<br />
<br />
=== Avoid infill by border textures ===<br />
If a <code>bordertexture</code> with a transparent center is used, the GUI can be informed via <code>infill="false"</code> that it does not have to be rendered.<br />
<br />
[[Image_Control#Available_tags_and_attributes|See here for additional information.]]<br />
<br />
=== Avoid almost opaque elements ===<br />
Consider using opaque elements instead of barely transparent ones. Especially on modern GPU's, this avoids rendering everything below such an element.<br />
<br />
=== Don't include unnecessary alpha layers in textures ===<br />
Including an alpha layer in a texture implies that it is used, even if the texture is fully opaque. The GUI has to treat such an element as transparent, with all the associated costs.<br />
<br />
=== Use single channel textures if possible ===<br />
A lot of GUI assets included in skins are delivered in a RGB format, even when they are greyscale. A single channel format saves disk space and might even reduce memory bandwidth in the future. Such textures can be colored by a <code>diffusecolor</code>.<br />
<br />
[[Category:Skin_development]]</div>Sarbeshttps://kodi.wiki/index.php?title=Debugging_via_Renderdoc&diff=242226Debugging via Renderdoc2022-06-08T07:30:34Z<p>Sarbes: /* Capturing a frame */</p>
<hr />
<div>{{mininav|[[Development]]|[[Skinning]]}}<br />
<br />
== What's Renderdoc? ==<br />
<br />
Renderdoc (https://renderdoc.org/) is a free graphics debugger for OpenGL and DirectX. It can record, store and replay frames rendered by an application. It exposes a plethora of information related to the commands the GPU receives. <br />
<br />
The scope of this tutorial is to give you an idea how it can be used to debug Kodi skins.<br />
<br />
== Capturing a frame ==<br />
<br />
Firstly, it is highly recommended to disable [[Advancedsettings.xml#smartredraw|smart redraw]] and [[Advancedsettings.xml#algorithmdirtyregions|dirty regions]] in Kodi.<br />
<br />
Install and run Renderdoc. Go to the "Launch Application" tab, select the Kodi executable and click "Launch"<br />
<br />
[[File:renderdoc_start.png]]<br />
<br />
Kodi should start up. Navigate to a view you want to analyze. In Renderdoc, select "Capture Frame(s) Immediately". The capture should show up. Activate it via double click.<br />
<br />
[[File:renderdoc_capture.png]]<br />
<br />
You can save this capture for future reference.<br />
<br />
== Analyzing frame composition ==<br />
<br />
Select the "Texture Viewer" tab. In the "Event Browser" on the left hand side, extend the "Colour Pass" list on the left. There you can 'replay' each draw command the GPU receives for this frame. On the main screen, you will see the state of the framebuffer at the selected GPU command.<br />
<br />
[[File:renderdoc_drawcalls.png]]<br />
<br />
On the right, you can switch to the input texture of the selected draw command. With a click on the thumbnail, it will show up on the main screen. The alpha channel is off by default, so some textures might look a bit odd.<br />
<br />
By right clicking on the main screen, the content of the selected pixel can be analyzed.<br />
<br />
== Overlays ==<br />
Some overlays have relevance for Kodi. Select one with the dropdown menu.<br />
<br />
[[File:renderdoc_overlays.png]]<br />
<br />
=== Highlight Drawcall ===<br />
Shows the boundary box of the selected draw call.<br />
<br />
=== Wireframe mesh ===<br />
Shows the geometry the current selected draw call is using.<br />
<br />
=== Quad Overdraw (Pass) ===<br />
Shows the accumulated amount of overdraw of the currently selected draw call. This is the most interesting overlay. It shows how many layers are making up the skin. The colors change with each layer applied. Right click on a pixel to see how many layers are drawn.<br />
<br />
[[File:renderdoc_overdraw.png]]<br />
<br />
Higher numbers should be investigated. See the Skin Optimization page for more info.<br />
<br />
== Performance estimation ==<br />
<br />
First of, any performance numbers gathered here are only indicative and might not reflect real world results. Numbers scale with current clock speed of the GPU. Memory bottlenecks are usually not encountered in this static test. Any results are only remotely comparative with other ones taken on the same system.<br />
<br />
Navigate to "Performance Counters". If the tab is not shown, enable it via "Window". Click "Capture counters", select generic (or other metrics if available) and hit "Sample counters".<br />
<br />
[[File:renderdoc_performance.png]]<br />
<br />
On the result screen, "GPU Duration (µs)" and "PS Invocations" are the most interesting fields. The first one indicates how long the draw call has taken, the latter describes how many pixels where put out during the call. Double clicking a call will select it in the Event Browser. From here, you can hop into the Texture Viewer to see what's taking so long.<br />
<br />
<br />
[[Category:Skin_development]]</div>Sarbeshttps://kodi.wiki/index.php?title=Debugging_via_Renderdoc&diff=242223Debugging via Renderdoc2022-06-07T21:33:18Z<p>Sarbes: Created page with "== What's Renderdoc? == Renderdoc (https://renderdoc.org/) is a free graphics debugger for OpenGL and DirectX. It can record, store and replay frames rendered by an applicati..."</p>
<hr />
<div>== What's Renderdoc? ==<br />
<br />
Renderdoc (https://renderdoc.org/) is a free graphics debugger for OpenGL and DirectX. It can record, store and replay frames rendered by an application. It exposes a plethora of information related to the commands the GPU receives. <br />
<br />
The scope of this tutorial is to give you an idea how it can be used to debug Kodi skins.<br />
<br />
== Capturing a frame ==<br />
<br />
Install and run Renderdoc. Go to the "Launch Application" tab, select the Kodi executable and click "Launch"<br />
<br />
[[File:renderdoc_start.png]]<br />
<br />
Kodi should start up. Navigate to a view you want to analyze. In Renderdoc, select "Capture Frame(s) Immediately". The capture should show up. Activate it via double click.<br />
<br />
[[File:renderdoc_capture.png]]<br />
<br />
You can save this capture for future reference.<br />
<br />
== Analyzing frame composition ==<br />
<br />
Select the "Texture Viewer" tab. In the "Event Browser" on the left hand side, extend the "Colour Pass" list on the left. There you can 'replay' each draw command the GPU receives for this frame. On the main screen, you will see the state of the framebuffer at the selected GPU command.<br />
<br />
[[File:renderdoc_drawcalls.png]]<br />
<br />
On the right, you can switch to the input texture of the selected draw command. With a click on the thumbnail, it will show up on the main screen. The alpha channel is off by default, so some textures might look a bit odd.<br />
<br />
By right clicking on the main screen, the content of the selected pixel can be analyzed.<br />
<br />
== Overlays ==<br />
Some overlays have relevance for Kodi. Select one with the dropdown menu.<br />
<br />
[[File:renderdoc_overlays.png]]<br />
<br />
=== Highlight Drawcall ===<br />
Shows the boundary box of the selected draw call.<br />
<br />
=== Wireframe mesh ===<br />
Shows the geometry the current selected draw call is using.<br />
<br />
=== Quad Overdraw (Pass) ===<br />
Shows the accumulated amount of overdraw of the currently selected draw call. This is the most interesting overlay. It shows how many layers are making up the skin. The colors change with each layer applied. Right click on a pixel to see how many layers are drawn.<br />
<br />
[[File:renderdoc_overdraw.png]]<br />
<br />
Higher numbers should be investigated. See the Skin Optimization page for more info.<br />
<br />
== Performance estimation ==<br />
<br />
First of, any performance numbers gathered here are only indicative and might not reflect real world results. Numbers scale with current clock speed of the GPU. Memory bottlenecks are usually not encountered in this static test. Any results are only remotely comparative with other ones taken on the same system.<br />
<br />
Navigate to "Performance Counters". If the tab is not shown, enable it via "Window". Click "Capture counters", select generic (or other metrics if available) and hit "Sample counters".<br />
<br />
[[File:renderdoc_performance.png]]<br />
<br />
On the result screen, "GPU Duration (µs)" and "PS Invocations" are the most interesting fields. The first one indicates how long the draw call has taken, the latter describes how many pixels where put out during the call. Double clicking a call will select it in the Event Browser. From here, you can hop into the Texture Viewer to see what's taking so long.</div>Sarbeshttps://kodi.wiki/index.php?title=File:Renderdoc_start.png&diff=242222File:Renderdoc start.png2022-06-07T21:30:33Z<p>Sarbes: File uploaded with MsUpload</p>
<hr />
<div>File uploaded with MsUpload</div>Sarbeshttps://kodi.wiki/index.php?title=File:Renderdoc_performance.png&diff=242221File:Renderdoc performance.png2022-06-07T21:30:32Z<p>Sarbes: File uploaded with MsUpload</p>
<hr />
<div>File uploaded with MsUpload</div>Sarbeshttps://kodi.wiki/index.php?title=File:Renderdoc_overlays.png&diff=242220File:Renderdoc overlays.png2022-06-07T21:30:31Z<p>Sarbes: File uploaded with MsUpload</p>
<hr />
<div>File uploaded with MsUpload</div>Sarbeshttps://kodi.wiki/index.php?title=File:Renderdoc_overdraw.png&diff=242219File:Renderdoc overdraw.png2022-06-07T21:30:30Z<p>Sarbes: File uploaded with MsUpload</p>
<hr />
<div>File uploaded with MsUpload</div>Sarbeshttps://kodi.wiki/index.php?title=File:Renderdoc_drawcalls.png&diff=242218File:Renderdoc drawcalls.png2022-06-07T21:30:29Z<p>Sarbes: File uploaded with MsUpload</p>
<hr />
<div>File uploaded with MsUpload</div>Sarbeshttps://kodi.wiki/index.php?title=File:Renderdoc_capture.png&diff=242217File:Renderdoc capture.png2022-06-07T21:30:28Z<p>Sarbes: File uploaded with MsUpload</p>
<hr />
<div>File uploaded with MsUpload</div>Sarbeshttps://kodi.wiki/index.php?title=Skin_Optimizations&diff=242204Skin Optimizations2022-06-06T17:20:13Z<p>Sarbes: Created page with "== Why to optimize skins == While the PC the skin is written on might be fast enough to render the GUI at 4k/60fps, it might be too expensive to run on lower end hardware. Thi..."</p>
<hr />
<div>== Why to optimize skins ==<br />
While the PC the skin is written on might be fast enough to render the GUI at 4k/60fps, it might be too expensive to run on lower end hardware. This page will give examples how to optimize skins, focusing on GPU performance.<br />
<br />
In general, the two most important resources on the GPU are memory bandwidth and computing power. Different systems might show different bottlenecks to render the GUI, but the following topics should help both.<br />
<br />
== Analysis via Renderdoc ==<br />
It is highly advised to use a tool like Renderdoc, a debugging program for computer graphics. While it offers a lot of features for graphics developers, it is also suitable for skinners to check for issues in the GUI layer compositing. With Renderdoc, the amount of overdraw can easily be judged.<br />
<br />
In a the future there will be a tutorial how to use RD.<br />
<br />
== Overdraw ==<br />
<br />
An important metric for performance evaluation is the amount of overdraw. Overdraw defines how many times a pixel gets rendered to, averaging across the whole screen. Using lots of layers increases the rendering costs. In order to have a performance target, a value should be picked when designing the skin. <br />
<br />
{| class="wikitable"<br />
|+ Typical overdraw values<br />
|-<br />
! Performance target !! Permissible Overdraw<br />
|-<br />
| Raspberry Pi 3, 1080p60 || 2.5<br />
|-<br />
| Raspberry Pi 4, 1080p60 || 3<br />
|-<br />
| Odroid C2, 1080p60 || 4.5<br />
|-<br />
| Intel HD 610, 1080p60 || 7<br />
|-<br />
| Intel HD 630, 2160p60 || 2.5<br />
|}<br />
<br />
Please take all of the values with a great pinch of salt. The actual value might vary when the system is busy, like when playing a video or rendering a visualization. Overdraw should be seen as a guide to keep the whole GUI experience consistent.<br />
<br />
Also, the performance target can be set lower when doing animations transitioning between menus. This will result in stutter on low-end systems during the transition, but the user experience is fine otherwise. On systems where the video is rendered via the GPU (Intel and similar "desktop" systems), this might be more noticable.<br />
<br />
As an example, a target of 3.5 permits the usage of one background layer (fanart) with one texture filter on top, while still leaving 1.5 pixel draws for UI elements.<br />
<br />
For comparison, the overdraw for The Estuary movie screen is about 4.2, while the amount for Confluence is about 1.8.<br />
<br />
== Reducing layer counts ==<br />
<br />
While Kodi can render dozens of layers on top of each other, each layer consumes quite a bit of rendering resources. The overall goal should be to use as few layers as possible. <br />
<br />
Typically, the most performance gains can be made by reducing the full-screen layers, but this is not exclusive to them.<br />
<br />
=== Diffuse texture usage ===<br />
The skinning engine has the ability to apply diffuse textures. While it might be tempting to get the same effect via a separate texture, it is faster. <br />
<br />
[[Texture_Attributes|See here for additional information.]]<br />
=== Coloring via diffusecolors ===<br />
In a lot of skins, coloring/shading is done by applying a white, featureless texture with a diffuse color to do color filtering. Most often, the same/similar effect can be obtained by applying the diffuse color to the underlying layer, so a whole layer can be saved.<br />
<br />
With Kodi 20 (Nexus), it will even be possible to animate the diffuse color (see https://github.com/xbmc/xbmc/pull/21400).<br />
<br />
=== Squashing filter layers ===<br />
In a lot of skins, various shadow effects get applied to the fanart in the background. Most often, such effects can be combined together into one texture to achieve a very similar effect. <br />
<br />
Combined into a diffuse texture, such savings could halve the rendering cost for some skins.<br />
<br />
=== Disabling invisible layers ===<br />
Always disable occluded layers. Even though they have no impact on the final result, they still have to be processed and rendered. This wastes a lot of resources.<br />
<br />
=== Avoid presenting assets multiple times ===<br />
Another pitfall is to present an asset (posters, fanart, ...) multiple times in the exact same location. While this has no or just a small impact on the ouptut, it eats up resources.<br />
<br />
== Misc improvements ==<br />
Other optimization considerations.<br />
<br />
=== Proper asset sizes ===<br />
One easy to solve issue is the use of too large assets. Check the resolution of the displayed icons. They should be suitably sized to the targeted rendering resolution (most often 1920x1080). When too large, it will result in increased usage of memory resources and in '''decreased''' image quality.<br />
<br />
For a lot of background effects, a smaller resolution texture might be used. Often enough, just 1/4th of the target resolution might do the trick (e.g. 960x540), especially when there are multiple layers.<br />
<br />
=== Avoid infill by border textures ===<br />
If a <code>bordertexture</code> with a transparent center is used, the GUI can be informed via <code>infill="false"</code> that it does not have to be rendered.<br />
<br />
[[Image_Control#Available_tags_and_attributes|See here for additional information.]]<br />
<br />
=== Avoid almost opaque elements ===<br />
Consider using opaque elements instead of barely transparent ones. Especially on modern GPU's, this avoids rendering everything below such an element.<br />
<br />
=== Don't include unnecessary alpha layers in textures ===<br />
Including an alpha layer in a texture implies that it is used, even if the texture is fully opaque. The GUI has to treat such an element as transparent, with all the associated costs.<br />
<br />
=== Use single channel textures if possible ===<br />
A lot of GUI assets included in skins are delivered in a RGB format, even when they are greyscale. A single channel format saves disk space and might even reduce memory bandwidth in the future. Such textures can be colored by a <code>diffusecolor</code>.</div>Sarbeshttps://kodi.wiki/index.php?title=Image_Control&diff=242203Image Control2022-06-06T14:54:03Z<p>Sarbes: /* Available tags and attributes */</p>
<hr />
<div>{{mininav| [[Skinning]] }}<br />
<section begin="main content" /><br />
The image control is used for displaying images in Kodi. You can choose the position, size, transparency and contents of the image to be displayed.<br />
<br />
<br />
=== Example ===<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<control type="image" id="1"><br />
<description>My first image control</description><br />
<left>80</left><br />
<top>60</top><br />
<width>250</width><br />
<height>200</height><br />
<visible>true</visible><br />
<colordiffuse>FFFFFFFF</colordiffuse><br />
<fadetime>200</fadetime><br />
<texture border="5" flipy="true" flipx="false">mytexture.png</texture><br />
<bordertexture border="5" infill="false">mybordertexture.png</bordertexture><br />
<bordersize>5</bordersize><br />
<aspectratio>keep</aspectratio><br />
</control><br />
</syntaxhighlight><br />
<br />
=== Image Size and Type Restrictions ===<br />
For the <texture> tags, and for all <texture> tags in other controls, there is a small set of rules that you should follow if at all possible:<br />
<br />
<br />
=== Size ===<br />
Images can be any size, though some graphics cards allow only power of 2 textures, so this may be a consideration. For the most case, it doesn't really matter what size things are - Kodi will quite happily load most files.<br />
<br />
<br />
=== Formats ===<br />
If you wish to use transparency, then use PNG. It is suggested that you use PNG and JPG as much as possible. Note that once the images are injected into Textures.xbt, they are not stored as JPG or PNG – rather they are stored in a native format used for GPUs for faster loading, such as ARGB or DXTc textures. The size of the images (in kb) is therefore not as important as the size of the images in pixels – so feel free to store them in a lossless (eg PNG) manner if you wish.<br />
<br />
The only exception to this is if you require an animated texture. In this case, we support only animated GIF. There are also some animated gifs that may not work. Use ImageReady CS and make sure you set the gif-anim to “restore to background” and they should work fine.<br />
<br />
<br />
=== Available tags and attributes ===<br />
In addition to the [[Default Control Tags|default control tags]], the following tags are available. Note that each tag is '''lower case only.''' This is important, as xml tags are case-sensitive.<br />
<br />
{| class="prettytable"<br />
! Tag !! Description<br />
|- <br />
| '''aspectratio'''<br />
| This specifies how the image will be drawn inside the box defined by <code><width></code> and <code><height></code>. [[Aspect Ratio|See here for more information]].<br />
|- <br />
| '''texture'''<br />
| Specifies the image file which should be displayed. [[Texture Attributes|See here for additional information about textures.]]<br />
|- <br />
| '''bordertexture'''<br />
| Specifies the image file which should be displayed as a border around the image. Use the <code><bordersize></code> to specify the size of the border. The <code><width></code>,<code><height></code> box specifies the size of the image plus border. Set the argument <code>infill="false"</code> to hint to the GUI that the inner portion of the border doesn't have to be rendered.<br />
|- <br />
| '''bordersize'''<br />
| Specifies the size of the border. A single number specifies the border should be the same size all the way around the image, whereas a comma separated list of 4 values indicates left,top,right,bottom values.<br />
|- <br />
| '''info'''<br />
| Specifies the information that this image control is presenting. Kodi will select the texture to use based on this tag. [[InfoLabels|See here for&nbsp;more information.]]<br />
|- <br />
| '''fadetime'''<br />
| This specifies a crossfade time that will be used whenever the underlying <texture> filename changes. The previous image will be held until the new image is ready, and then they will be crossfaded. This is particularly useful for a large thumbnail image showing the focused item in a list, or for fanart or other large backdrops.<br />
|- <br />
| '''background'''<br />
| For images inside a container, you can specify background="true" to load the textures in a background worker thread.<br />
|}<br />
<br />
=== Texture Loading ===<br />
==== Normal texture loading ====<br />
The only textures loaded by Kodi are the ones currently visible. Nothing displays on the screen until all the images have been loaded in memory, this can result in "jerky" scrolling through panel containers. As you scroll down, Kodi will delay the scrolling animation until all of the images in the next row are loaded.<br />
<br />
==== Background loading ====<br />
Images are loaded one at a time in a background worker thread and are shown as soon as xbmc processes them. Has the benefit that images can be loaded into memory before they're visible, resulting in smoother scrolling and transitions.<br />
<br />
==== Preloading ====<br />
Used to automatically load the next items (or rows/columns in the case of a panel) while scrolling. Currently limited to 2.<br />
<br />
<section end="main content" /><br />
<br />
<br />
[[Category:Skin development]]</div>Sarbeshttps://kodi.wiki/index.php?title=Image_Control&diff=242202Image Control2022-06-06T14:51:11Z<p>Sarbes: /* Example */</p>
<hr />
<div>{{mininav| [[Skinning]] }}<br />
<section begin="main content" /><br />
The image control is used for displaying images in Kodi. You can choose the position, size, transparency and contents of the image to be displayed.<br />
<br />
<br />
=== Example ===<br />
<syntaxhighlight lang="xml" enclose="div"><br />
<control type="image" id="1"><br />
<description>My first image control</description><br />
<left>80</left><br />
<top>60</top><br />
<width>250</width><br />
<height>200</height><br />
<visible>true</visible><br />
<colordiffuse>FFFFFFFF</colordiffuse><br />
<fadetime>200</fadetime><br />
<texture border="5" flipy="true" flipx="false">mytexture.png</texture><br />
<bordertexture border="5" infill="false">mybordertexture.png</bordertexture><br />
<bordersize>5</bordersize><br />
<aspectratio>keep</aspectratio><br />
</control><br />
</syntaxhighlight><br />
<br />
=== Image Size and Type Restrictions ===<br />
For the <texture> tags, and for all <texture> tags in other controls, there is a small set of rules that you should follow if at all possible:<br />
<br />
<br />
=== Size ===<br />
Images can be any size, though some graphics cards allow only power of 2 textures, so this may be a consideration. For the most case, it doesn't really matter what size things are - Kodi will quite happily load most files.<br />
<br />
<br />
=== Formats ===<br />
If you wish to use transparency, then use PNG. It is suggested that you use PNG and JPG as much as possible. Note that once the images are injected into Textures.xbt, they are not stored as JPG or PNG – rather they are stored in a native format used for GPUs for faster loading, such as ARGB or DXTc textures. The size of the images (in kb) is therefore not as important as the size of the images in pixels – so feel free to store them in a lossless (eg PNG) manner if you wish.<br />
<br />
The only exception to this is if you require an animated texture. In this case, we support only animated GIF. There are also some animated gifs that may not work. Use ImageReady CS and make sure you set the gif-anim to “restore to background” and they should work fine.<br />
<br />
<br />
=== Available tags and attributes ===<br />
In addition to the [[Default Control Tags|default control tags]], the following tags are available. Note that each tag is '''lower case only.''' This is important, as xml tags are case-sensitive.<br />
<br />
{| class="prettytable"<br />
! Tag !! Description<br />
|- <br />
| '''aspectratio'''<br />
| This specifies how the image will be drawn inside the box defined by <code><width></code> and <code><height></code>. [[Aspect Ratio|See here for more information]].<br />
|- <br />
| '''texture'''<br />
| Specifies the image file which should be displayed. [[Texture Attributes|See here for additional information about textures.]]<br />
|- <br />
| '''bordertexture'''<br />
| Specifies the image file which should be displayed as a border around the image. Use the <code><bordersize></code> to specify the size of the border. The <code><width></code>,<code><height></code> box specifies the size of the image plus border.<br />
|- <br />
| '''bordersize'''<br />
| Specifies the size of the border. A single number specifies the border should be the same size all the way around the image, whereas a comma separated list of 4 values indicates left,top,right,bottom values.<br />
|- <br />
| '''info'''<br />
| Specifies the information that this image control is presenting. Kodi will select the texture to use based on this tag. [[InfoLabels|See here for&nbsp;more information.]]<br />
|- <br />
| '''fadetime'''<br />
| This specifies a crossfade time that will be used whenever the underlying <texture> filename changes. The previous image will be held until the new image is ready, and then they will be crossfaded. This is particularly useful for a large thumbnail image showing the focused item in a list, or for fanart or other large backdrops.<br />
|- <br />
| '''background'''<br />
| For images inside a container, you can specify background="true" to load the textures in a background worker thread.<br />
|}<br />
<br />
<br />
=== Texture Loading ===<br />
==== Normal texture loading ====<br />
The only textures loaded by Kodi are the ones currently visible. Nothing displays on the screen until all the images have been loaded in memory, this can result in "jerky" scrolling through panel containers. As you scroll down, Kodi will delay the scrolling animation until all of the images in the next row are loaded.<br />
<br />
==== Background loading ====<br />
Images are loaded one at a time in a background worker thread and are shown as soon as xbmc processes them. Has the benefit that images can be loaded into memory before they're visible, resulting in smoother scrolling and transitions.<br />
<br />
==== Preloading ====<br />
Used to automatically load the next items (or rows/columns in the case of a panel) while scrolling. Currently limited to 2.<br />
<br />
<section end="main content" /><br />
<br />
<br />
[[Category:Skin development]]</div>Sarbes