Describe the bug
While working with the ThemeShadow API, I saw the note in the docs about the 5 shadow pair limit. I was hoping this just meant definitions of shadows as they can be attached to multiple items for re-use. However, I found it meant 5 physically cast shadows... ☹ This limits options for these consistent performant shadows on design elements or lists...
Steps to reproduce the bug
Steps to reproduce the behavior:
Expected behavior
See all shadows.
Actual Behavior
Shadows on 'Pool' tiles missing:
Screenshots
Version Info
| Windows 10 version | Saw the problem? |
| :--------------------------------- | :-------------------- |
| Insider Build (19584) | Yes |
| November 2019 Update (18363) | |
| May 2019 Update (18362) | |
| October 2018 Update (17763) | |
| April 2018 Update (17134) | |
| Fall Creators Update (16299) | |
| Creators Update (15063) | |
| Device form factor | Saw the problem? |
| :-------------------- | :------------------- |
| Desktop | Yes |
| Mobile | |
| Xbox | |
| Surface Hub | |
| IoT | |
Additional context
Related to making helper for #1009
Actually, I forgot that I didn't have the slider set for a value, so I can define multiple shadows like this:
This appears to be casting more than 5 shadows (10).
However, when I did the same in a List sharing the same BackgroundGridShadow ThemeShadow set for each container still, it stopped at 5:
<ListView HorizontalAlignment="Center" VerticalAlignment="Center"
ItemsSource="{x:Bind Items}">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="0,0,0,8"/>
<Setter Property="Shadow" Value="{StaticResource BackgroundGridShadow}"/>
<!--<Setter Property="Translation" Value="0,0,64"/>--> <!-- Issue #2130 -->
<Setter Property="ex:ShadowExtensions.Translation" Value="0,0,8"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate x:DataType="x:String">
<Border BorderBrush="Black" BorderThickness="1" CornerRadius="8" Background="White">
<TextBlock Padding="16" Text="{x:Bind}" FontWeight="SemiBold" Foreground="Black"/>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
So, now I'm more confused about what the actual limit is... 🤷♂️
(Also, using Win+Shift+S for a snippet makes all the shadows disappear...)
Related #2130
@chigy Are you the right owner for this? @jesbis fyi.
@StephenLPeters , yes, you can assign it to me.
I'm curious, what is the reasoning for the shadow limits? WinUI is desktop-oriented and shadows can be optimized enough to use in a lot of places. They should be added during composition as well. The limit is much too small especially as depth is one of the foundations of the Fluent design system. On top of that, just like reveal and acrylic brushes, they could be disabled automatically by the system on lower-end hardware.
@robloo This is a performance limitation. The CompositionProjectedShadow implementation used by ThemeShadow focused on high quality, which currently includes relatively high expense (in part due to potentially drawing a shadow at multiple depths, depending on the z-depth of the elements the shadow is casting on). In system XAML, all of that expense of drawing shadows happens in the system compositor in dwm.exe. This means that if an app has too many shadows, it can potentially slow down the entire system if each frame drawn by the system compositor needs to draw too many of those shadows, even if that isn't the application the user is currently focused on.
There are ideas of how to improve the performance some without impacting quality, but there haven't yet been resources to attempt that. It is also possible we could change this limit in WinUI 3 when the rendering is happening in-proc rather than in dwm.exe, but we need to make sure that doesn't cause problems for the future.
Overall, we agree this limit today results in scenarios where ThemeShadow can't be used. We definitely want to improve this, and need to evaluate a variety of different options. It may be necessary to implement multiple changes.
@codendone Thanks for the background, I did expect this was a performance limitation. That said, there could be multiple types of shadows -- with much lower default quality, or that don't take into account different z-depths (they just cast a fixed shadow under the parent that's blended regardless of z-depth below i.e. a simple 2D shadow based on only the parent). Also a 'Quality' property used to tell the app when quality isn't so important (and overridden by the system if needed).
I'm hoping improvements to limitations like this do find their way into WinUI 3.0. It honestly seems the composition system just doesn't handle this well and it needs some architecture improvements to support this better. I know you guys are doing a lot of hard work at the moment and WinUI 3.0 is the obvious priority.
As always, thanks for the feedback!
Most helpful comment
@codendone Thanks for the background, I did expect this was a performance limitation. That said, there could be multiple types of shadows -- with much lower default quality, or that don't take into account different z-depths (they just cast a fixed shadow under the parent that's blended regardless of z-depth below i.e. a simple 2D shadow based on only the parent). Also a 'Quality' property used to tell the app when quality isn't so important (and overridden by the system if needed).
I'm hoping improvements to limitations like this do find their way into WinUI 3.0. It honestly seems the composition system just doesn't handle this well and it needs some architecture improvements to support this better. I know you guys are doing a lot of hard work at the moment and WinUI 3.0 is the obvious priority.
As always, thanks for the feedback!