WPF Perf: RenderCapability.Tier & DesiredFrameRate

本文介绍如何使用WPF中的RenderCapability.Tier和Storyboard.DesiredFrameRate两个关键API来优化应用程序性能,包括根据不同硬件级别调整渲染质量和帧率以节省CPU资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blogs.msdn.com/b/henryh/archive/2006/08/23/719568.aspx

 

In this post, I’m going to talk about two key API’s for performance in WPF.  These are RenderCapability.Tier and Storyboard.DesiredFrameRate.  In this post, I’m going to show:

 

  1. How to leverage RenderCapability.Tier to scale your app up or down.
  2. How to use RenderCapability.Tier in markup.
  3. How to apply DesiredFrameRate to reduce CPU consumption.

RenderCapability.Tier

For the machine on which it’s run, RenderCapability.Tier signals the machine’s hardware capabilities.  Tier=0 means software rendering; Tier=2 is hardware rendering (for those features that can be rendered in hardware); Tier=1 is a middle ground (some things in hardware and some in software.)  You can probably see how this might be useful to scale up or down the richness of an application depending on the hardware.

 

(Note: RenderCapability.Tier is an integer value using the high word to indicate the tier.  You’ll need to shift by 16 bits to get the corresponding tier values.  Adam Smith posts about why this was chosen.)

Storyboard.DesiredFrameRate

The second API I mentioned was Storyboard.DesiredFrameRate (DFR.)  DFR allows you to specify, manually, what the frame rate “should” be (the animation system attempts to get as close as possible to the DFR value but there are no guarantees.)  By default, WPF attempts 60 fps.  The up side to this is that animations look better; the down side is that you may not need 60 fps but you may be spending the extra CPU cycles.

Putting Them Together

You can use RenderCapability.Tier in markup with a small helper class.  The trick is to wrap up the property in a DependencyProperty.  From there, the property can be used to set DFR.  Below, you’ll find both the code for the RenderCapability.Tier, how to use it in markup and how to set DesiredFrameRate.  I picked different DFR values for the different Tiers.  The resulting UI isn't that exciting (a spinning Button) but it demonstrates the concept.

 

using System;
using System.Windows;
using System.Windows.Media;
 
namespace PerformanceUtilities
{
    public static class RenderCapabilityWrapper
    {
        public static readonly DependencyProperty TierProperty =
            DependencyProperty.RegisterAttached(
                "Tier",
                typeof(int),
                typeof(PerformanceUtilities.RenderCapabilityWrapper),
                new PropertyMetadata(RenderCapability.Tier >> 16));
       
        public static int GetTier(DependencyObject depObj)
        {
            return (int)TierProperty.DefaultMetadata.DefaultValue;
        }
    }
}


 

<Border
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:Perf="clr-namespace:PerformanceUtilities;assembly=PerfTier"
  Background="silver"
> 
 
  <Border.Resources>
    <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
      <Style.Triggers>
        <Trigger
        Property="Perf:RenderCapabilityWrapper.Tier" Value="2">
          <Setter Property="Tag" Value="60"/>
        </Trigger>
        <Trigger
        Property="Perf:RenderCapabilityWrapper.Tier" Value="1">
          <Setter Property="Tag" Value="30"/>
        </Trigger>
        <Trigger
        Property="Perf:RenderCapabilityWrapper.Tier" Value="0">
          <Setter Property="Tag" Value="15"/>
        </Trigger>
      </Style.Triggers>
    </Style>
  </Border.Resources>
 
 
  <Button Width="80" Height="80" Name="MyButton"
  Content="{Binding RelativeSource={RelativeSource Self}, Path=Tag}">
    <Button.Triggers>
      <EventTrigger RoutedEvent="FrameworkElement.Loaded">
        <BeginStoryboard>
          <Storyboard RepeatBehavior="Forever"
          Storyboard.DesiredFrameRate="{Binding ElementName=MyButton,
          Path=Tag}">
 
            <DoubleAnimation
            Storyboard.TargetName="MyAnimatedTransform"
            Storyboard.TargetProperty="(RotateTransform.Angle)"
            From="0.0" To="360" Duration="0:0:10" />
          </Storyboard>
        </BeginStoryboard>
      </EventTrigger>
    </Button.Triggers>
 
    <Button.RenderTransform>
      <RotateTransform CenterX="40" CenterY="40"
      x:Name="MyAnimatedTransform"/>
    </Button.RenderTransform>
 
  </Button>
 
</Border>


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值