[WinRT] XAML アニメーションは GPU のパワーを使い切れるか?

Windows ストア アプリで C++/CX を使ってゲームを使えば、グラフィックボードの性能を最大限に引き出せることが分かっているのですが、では、XAML でのアニメーション(主に storyboard)の場合は、どのくらいグラフィックボードの GPU を使っているか?ってのを調べてみます。
目的としては「小難しい C++/CX とか DirectX を使わなくても、XAML のアニメーション効果を使えばそこそこゲームが作れるのでは?」ってところです。実際、C++/CX は高度な3D効果の使い、単純なテキスト表示などは XAML で表示させる、という手法が Microsoft より紹介されているわけで、そのあたりは、そのあたりで。

■ベンチマークアプリを作る

単純に5000個の円(Ellipse)を表示させて、storyboard で動かしています。storybaord クラスのコピーには、以前作った Storyboard.Clone を少し修正して使っています。

List<Storyboard> sbs;
/// <summary>
/// 円を作成
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CreateClick(object sender, RoutedEventArgs e)
{
    var rnd = new Random();

    // 100個のEllipseを適当に並べる
    var xml = @"
<Ellipse
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
Fill=""#FFF4F4F5"" HorizontalAlignment=""Left""
Height=""50"" Margin=""94,137,0,0"" Grid.Row=""1"" Stroke=""Black"" VerticalAlignment=""Top""
Width=""50"" RenderTransformOrigin=""0.5,0.5"">
<Ellipse.RenderTransform>
<CompositeTransform/>
</Ellipse.RenderTransform>
</Ellipse>
";
    sbs = new List<Storyboard>();
    for (int i = 0; i < 5000; i++)
    {
        object obj = XamlReader.Load(xml);
        Ellipse el = obj as Ellipse;

        Canvas.SetLeft(el, 0);
        Canvas.SetTop(el, 0);
        canvas.Children.Add(el);

        var sb = sbMove.Clone();
        sb.SetTarget(el);
        sb.AutoReverse = true;
        sb.RepeatBehavior = RepeatBehavior.Forever;
        int x1 = rnd.Next(800);
        int y1 = rnd.Next(800);
        int x2 = rnd.Next(800);
        int y2 = rnd.Next(800);
        ((DoubleAnimation)sb.Children[0]).From = x1;
        ((DoubleAnimation)sb.Children[1]).From = y1;
        ((DoubleAnimation)sb.Children[0]).To = x2;
        ((DoubleAnimation)sb.Children[1]).To = y2;
        TimeSpan ts = new TimeSpan(0, 0, rnd.Next(5) + 1);
        ((DoubleAnimation)sb.Children[0]).Duration = ts;
        ((DoubleAnimation)sb.Children[1]).Duration = ts;

        ((ColorAnimation)sb.Children[2]).Duration = ts;
        switch (rnd.Next(3))
        {
            case 0: ((ColorAnimation)sb.Children[2]).To = Windows.UI.Colors.Red; break;
            case 1: ((ColorAnimation)sb.Children[2]).To = Windows.UI.Colors.Yellow; break;
            case 2: ((ColorAnimation)sb.Children[2]).To = Windows.UI.Colors.Blue; break;
        }
        sbs.Add(sb);
    }
}

private void StartClick(object sender, RoutedEventArgs e)
{
    // アニメーション開始
    foreach (var sb in sbs)
    {
        sb.Begin();
    }
}

private void StopClick(object sender, RoutedEventArgs e)
{
    // アニメーション停止
    foreach (var sb in sbs)
    {
        sb.Stop();
    }
    this.sbMove.Stop();
}

動かすとこんな感じになります。円が5000個(半分ほど見えていませんが)うにょうにょと動きます。

■CPU と GPU の負荷を見てみる。

Process Explorer で XamlBenchMark の負荷をみていくと、GPU を 25% ほど使った状態になります。この PC だとそれほど重くないのですが、うまく動かない場合は、1000 個位に減らして動かしてみてください。

この時の CPU 負荷は、26% 程度です。GPU を使わない場合(グラフィックボードを積まない場合)がどうなるのかは、別の PC で検証したいと思います。

プログラムを修正して、ぱらぱらアニメを1000個位動かしてみたいですね。体感速度がそれほど落ちるものでなければ、それなりのアクションパズルゲームとかが C#+XAML+storyboard の組み合わせでできるのではないか、と考えています。

■サンプルのダウンロード

ベンチマークのダウンロードは以下からできます XamlBenchMark.zip

カテゴリー: C#, WinRT, XAML パーマリンク

[WinRT] XAML アニメーションは GPU のパワーを使い切れるか? への1件のコメント

  1. masuda のコメント:

    ちなみに、5000個の円を surface RT で実行させると作成時にがっつりと止まってしまうので、1000程度に変更したほうが無難。後でサンプルも変えておきます。

コメントは停止中です。