In our app, we have some scrolling credits in a ChildWindow
. When showing this window, our CPU utilization is very high. The text is using a BitmapCache
and hardware acceleration is enabled. Even after removing the clipping rectangle and the drop shadow from the child window, the CPU usage climbs to 80-90%. When I enable redraw region visualization, I see that only the scrolling text is getting redrawn, so I'm unsure why the CPU is going crazy. I tried animating both Canvas.Top
and the TranslateY
property of a CompositeTransform
to do the scrolling.
Any ideas as to what may be causing this animation to be so expensive? Are there any good articles out there that have recommendations for optimizing animations in general? Here's my XAML:
<c:ChildWindow xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Class="OurNamespace.UI.Views.AboutWindow"
Title="About Our App" Width="575"
Height="330" Style="{StaticResource ChromelessChildWindowStyle}"
mc:Ignorable="d"
MouseRightButtonDown="ChildWindow_MouseRightButtonDown"
Background="Black">
<Grid x:Name="LayoutRoot" CacheMode="BitmapCache">
<Grid.Triggers>
<EventTrigger RoutedEvent="Canvas.Loaded">
<BeginStoryboard>
<Storyboard Storyboard.TargetName="CreditsTransform"
Storyboard.TargetProperty="TranslateY">
<DoubleAnimation To="-750" RepeatBehavior="Forever"
Duration="0:0:30"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Image HorizontalAlignment="Left" VerticalAlignment="Top"
Source="/Assets/Graphics/SplashAbout/OurBackground.png"/>
<Grid Height="150" Width="570" HorizontalAlignment="Right"
Margin="0,0,0,80" VerticalAlignment="Bottom">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock x:Name="AppVersionTextBlock" Margin="10,0"
VerticalAlignment="Center" FontFamily="Arial"
FontSize="12" Foreground="White"
Text="{Binding VersionInfo, FallbackValue=Version 2.0.0}"
TextWrapping="Wrap"/>
<TextBlock x:Name="FirmwareVersionTextBlock" Margin="10,0"
VerticalAlignment="Center" FontFamily="Arial" FontSize="12"
Foreground="White" Text="{Binding FirmwareVersion.Value, FallbackValue=Firmware Version 1.0.0}"
TextWrapping="Wrap"
Visibility="{Binding FirmwareVersionVisibility.Value}"
TextAlignment="Right"/>
<Canvas Margin="0" Grid.Row="1" x:Name="Viewport">
<Canvas.Clip>
<RectangleGeometry Rect="0,0,575,120"/>
</Canvas.Clip>
<TextBlock FontFamily="Arial" FontSize="12" Width="555"
Foreground="White" TextWrapping="Wrap" Canvas.Left="10"
Text="{Binding Credits}" x:Name="Credits"
TextAlignment="Center" RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<CompositeTransform TranslateY="0" x:Name="CreditsTransform"/>
</TextBlock.RenderTransform>
<TextBlock.CacheMode>
<BitmapCache/>
</TextBlock.CacheMode>
</TextBlock>
</Canvas>
</Grid>
<TextBlock Foreground="White" Text="{Binding CopyrightInfo, FallbackValue=© 2010 Our Company}"
TextWrapping="Wrap" Width="413" FontSize="10"
FontFamily="Arial" Height="44" HorizontalAlignment="Right"
Margin="0,0,30,21" VerticalAlignment="Bottom"/>
<Button x:Name="CancelButton" Width="575" Height="330" Opacity="0"
Click="CancelButton_Click" HorizontalAlignment="Right"
Margin="0" VerticalAlignment="Bottom"/>
</Grid>
</c:ChildWindow>
Update:
The CPU problem was not directly related to the ChildWindow
itself but to the DropShadowEffect
objects underneath which Silverlight was wastefully re-rendering. I've added an answer to describe how I worked around this.