WPFでFreeze

今日、飲み会をしました。
メンバー的には関西MS系勉強会でおなじみのディープテクノロジーでおなじみのよねさんとデザイン&グラフィックスでお馴染みの若社長であるみつばたんと女性エンジニアの4人飲み会。

そこで、WPFとDirect2Dの連携をオフスクリーンレンダリングとImageコントロールで解決するってパターンでもそこそこ速い。(要出典)
って話を耳にした。実はちょっとレンダリングコストの話は後回しにしようかと思っててんけど、そう言われちゃうと「そうなん?」ってなるやんか。だって人間だもの。

で、もっぺんWPFボトルネックを確認しようと思って、10万本の線を引いたらどれくらいかかるか図りなおしたわけ。
ざっくり書くとこういう感じ。

static Pen pen = new Pen(Brushes.Black, 0.3);
--snip--
protected override void OnRender(DrawingContext drawingContext)
{
    var sw = new Stopwatch();
    sw.Start();
    for (var i = 0; i < 100000; i++)
    {
        var x1 = rnd.Next() % 10000;
        var y1 = rnd.Next() % 10000;
        var x2 = rnd.Next() % 10000;
        var y2 = rnd.Next() % 10000;

        var p1 = new Point(x1, y1);
        var p2 = new Point(x2, y2);
        drawingContext.DrawLine(pen, new Point(x1, y1), new Point(x2, y2));
    }
    sw.Stop();
    Debug.WriteLine(sw.ElapsedMilliseconds);
}

実はメンバに持ってるPenをFreezeせんかったら1FPS出ないくらい糞重い。(なんで?)
それをFreezeさせたら10万本の半透明の線が40msで描ける。20FPSぐらいか。
普通に考えたら10万本を無造作に描くことないし、文字描画は恐らく100倍くらい遅いやろけど30FPS出るなら文字だけ遅延レンダリングとかする手でなんとでもなりそう。

いろいろ作戦考えてたけど、ひとまずDirect2D使わんとWPFで実装進める方向で行く気になった。(Direct2Dのオフスクリーンレンダリングは切り札)

10万本引くとこんな感じ。5000エンティティやったとしても、こんなに描く必要ないわな。
WPFでもサクサク動く確率が高いような気がしてきた。(飲み会の後なので、べろんべろんの思考力!)

ボチボチ進めていこう。レンダリング以外のとこの方がやること多いんやしね。

ホットウーロン茶でべろんべろんに酔っぱらったのは私だけ。