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





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