ページ

2009年4月30日木曜日

[WPF][Silverlihgt] プリプロセッサを使って SL と WPF の XAML の非互換部分をどうにかする

Silverlight の XAML と WPF のそれはよく似てるんですが非互換部分も結構あります。
それを VC++ のプリプロセッサを使って何とかしてしまうと言う方法が
Using the preprocessor to share incompatible XAML between SL and WPF ? Part 1
で紹介されています。

何とかすると言っても、使うのはプリプロセッサですから、XAML 上に

<TextBlock
#if SILVERLIGHT
Text="This is in Silverlight"
#else
Text="This is in WPF"
#endif
/>

というように書いておくってことです。
もちろん、標準では #if なんて対応していませんから、ビルド時にプリプロセッサを呼び出すように PreprocessXaml.targets ファイルを用意しておき、これを自分の csproj ファイルに追記してやるという方法です。

紹介されているのは以上なんですが、#if を書きこんだ XAML ファイルをそのままでは Blend で読み込めないとかいろいろと制限も出て来そうですね。
記事のタイトルに “Part 1” と付いてるので、今後も続くのかな?


[C++] 細かい手動最適化 (けど、結構効果あるのね)

Optimize Your Code: Matrix Multiplication より
結果を見て 「へぇ」 と思ったので紹介。

ところで、このブログの方、Microsoft の C++ Shanghai team のデベロッパと書いてあるけど、Shanghai チームって上海のことなのかな?それともそういうコード名のプロジェクトがある?

紹介してるのは n×n の正方行列の積を求めるコード。

Version 1 はごく普通にループ回して結果を求めるコード。
何の工夫もなし。

Version 2 は内側のループで一時変数を使うようにしたちょっとした改良。
最初これを見たとき 「これくらいはオプティマイザが勝手に最適化してくれるんじゃないかな?」 と思ったんですが、してくれないんですね。
ちゃんと解説が書いてあります。
「”result” が “m1” か “m2” の別名になってる (言い換えると “result” が “m1” か “m2” と同じところを参照している) かどうかをオプティマイザには判断付かないので result[i][j] に毎回バカ正直にメモリ書き込みすることになる」
なるほど、そりゃそうだ。

Version 3 は Version 2 に後ろの行列を計算前にひっくり返しておいて、計算後に元に戻すという処理を加えたもの。
これまた、「いったい何の意味が?」 と思ったんですが解説を読んで納得。
「この最適化はトリッキー。(Version 2 のコードの) プロファイルを取ってみれば、多数のキャッシュミスしてるのがわかるはず。行列をひっくり返してから計算すると m1[i] と m2[j] のシーケンシャルアクセスだけになる。これによってメモリリードのパフォーマンスがものすごく良くなる」
なるほど、先読みキャッシュの機構があるってことを前提にすればシーケンシャルアクセスの方が速くなるわけですね。

Version 4 は、、、なんだこりゃ?
float と double 用に SSE3 を使った実装か。
もう、こうなると C++ じゃないなw
つか、_mm_hadd_ps とかってのは Visual C++ の標準機能だったのか。こんなの知らんかったよ。

あとはそれぞれを Visual C++ 2010 CTP の Parallel ライブラリとラムダ式を使って並列化した実装。
へぇ、C++ でもラムダ式が使えるようになるのか。
これって C++0x ?
ラムダ式の頭についてる [&] は何だ?
検索してみた。。。変数のキャプチャ方法を指定。= でコピー、& で参照。[&, hoge] のように書くと hoge をコピーで、それ以外を参照で、といった指定もできる。
C++ もすごいことになっていくなぁ。

で、500×500の行列でやってみた表が載っています。
個人的には、Version 3 の改良がかなり効果があるのが意外でした。特に long long や double などサイズが大きくなるとかなり効果が出てますね。
500×500 の行列をひっくり返して、計算後にまた元にひっくり返して元に戻す、と処理量はだいぶ増えてるはずなのにメモリリードがシーケンシャルになるようにしただけでここまで明らかな効果があるとは。
あとは、2コアの Core2Duo だと Parallel の効果は微々たるものだけど、4コアの Xeon になるとかなりの効果があるっていうのも、まぁ、あたりまえだけれども、はっきりと数値に出てますね。


2009年4月28日火曜日

[Silverlight] Silverlight 3 で TextBox のキャレットの色も変えられる

Silverlight 3 Hidden Features: TextBox.CaretBrush より
「Silverlight 3 にはたくさんおもしろ機能があるし新機能もある。たくさんのブロガーがそいつらを紹介しているよね。けど、俺は忘れられちゃってるようなことにこそスポットを当てたいんだぜ。今日は TextBox.CaretBrush だ!」
いや、ほんとにこんな口調なのかどうかはわかりませんが(笑)、まぁ、こんなような意味の文章で始まってます。

んで、本題。

Silverlight 2 でキャレット (テキストボックスで文字を入力するときに点滅してるやつ) の色を変えることはできなかったので、TextBox の背景色を黒くしたりしているとキャレットが見えなくて困ることになります。
Silverlight 3 では CaretBrush=”White” のようにキャレットの色を指定できるようになりました。
プロパティ名からわかるようにブラシなのでグラデーションブラシなども指定できます。
(こんな細いものにグラデーションかけても意味ないでしょうが)

ちなみに、文字列を選択してるときのは色は Silverlight 2 でも 3 でも SelectionForeground と SelectionBackground で指定できます。

ということだそうです。
確かにこれは細かいですが、キャレットが見えないってのはユーザビリティに直結しますからすばらしい改善と言っていいんじゃないかと思います。
まぁ、私は、Silverlight 2 でキャレットの色が変えられないってことすら知らなかったんですけどね(^^;


2009年4月22日水曜日

[WPF][Silverlight] ビヘイビア(behavior)- Blend 3 との連携機能

It took me under 5 minutes to realize the power of behaviors! より

ええと、↑に書かれてることをギュッと圧縮すると以下みたいなことかな?

今までは Blend を使ってできることはデザインに関することだけでした。
たとえば 「クリックイベントのときに何をするか」 なんていうことはコードを書くしかありません。

それがビヘイビアを使うとこんなことができるようになります。
まずはアクションを用意。
たとえば以下みたいなの。

using System;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Expression.Interactivity;

public class SampleAction : TargetedTriggerAction<FrameworkElement> { protected override void Invoke(object parameter) { MessageBox.Show("Click!") } }

そして Blend 3 ではイベントとアクションを簡単に関連付けられます。
たとえば、ボタンにアクションをドラッグ&ドロップするだけ。
アクションにプロパティを持たせたりといったこともできますし、デベロッパがあらかじめ必要となるアクションを作っておけばあとは Blend 3 上でそれらを関連付けしていくことができます。

--

なるほど、確かにこれは便利そう。
Blend 3 Behaviors: A Sample Action
↑ではもう少し詳しく、アクションにプロパティ (もちろん依存プロパティです) を持たせたりする例が載っていました。


[Silverlight] 無料 Silverlight ゲーム集サイト silverarcade.com オープン

以前 「[Silverlight] XNA 2D ゲームが Silverlight で動く?」 のときに書いた http://silverarcade.com/ がオープンしてました。
すでにいくつかのゲームが遊べます。
(パズルゲームとかはやりだすと止まらなくなるからやばい)

どうやらこのサイトは単にゲームを載せるというだけでなく、Silverlight によるゲームのコミュニティを目指しているようです。
トップページに “The money we make by displaying ads is shared with the people who created the games.” (広告表示で得たお金をゲームの製作者で分けるようにしたい) といったことが書かれてますし、どちらかと言うと製作者側のコミュニティを目指しているんじゃないかと思います。


[Silverlight] Siverlight 3 の Out of Browser だとマウスホイールが捕捉できない?

昨日の 「[Silverlight] Silverlight 3 の Out of Browser とアセンブリ・キャッシングは混ぜて使えない (beta 1)」 を試してたときに気付きました。
試したソースが Silverlight.FX を使ってマウスホイールを使えるようにした DataGrid だったんですが、Out of Browser にするとマウスホイールが効かなくなってました。
考えてみると当然で、Silverlight.FX も特殊なことをやってるわけではなくて、内部では HtmlPage.Window.AttachEvent(“onmousewheel”, OnMouseWheel); なんて感じで HTML のイベントにアタッチしています。
Out of Browser では名前の通りブラウザの外なので HTML もありません。
どうなるのか確認してはいませんが、きっと AttachEvent なんかは無視されているんでしょう。
ですから当然 onmousewheel イベントなんかも無いわけで、マウスホイールなどを捕捉できないわけです。

って、こりゃどうしたらいいんだ?
今どき、マウスホイールを使えないアプリなんて考えられないんだが。

まったく誰も気づいてないなんてことは考えられないので検索してみた。
OUT-OF-BROWSER EXPERIENCES
↑で Bigsby さんが 「Silverlight 3 でのマウスホイールについては聞いたことないけど、Out of Browser のときにスクリプトのイベントはどうなるの?」 みたいなことをコメントしています。
それに対して heuertk さんが 「マウスホイールのネイティブサポートは無い予定だけど、プロジェクトにドロップして使えるヘルパクラスライブラリを用意する」 みたいな返事をしています。
この heuertk さんって Method ~ of ~ failed の Tim Heuer さんですね。(About Me を見ればわかりますが、Silverlight のプログラムマネージャの方)

というわけで、beta 1 では Out of Browser するとマウスホイールが使えませんが、そのうちにはちゃんと使えるようになるみたいです。


2009年4月21日火曜日

[Silverlight] Silverlight 3 の Out of Browser とアセンブリ・キャッシングは混ぜて使えない (beta 1)

Silverlight 3 ? Out of Browser Applications with Cached Extensions で知りました。
少なくとも Silverlight 3 beta 1 では Out of Browser と アセンブリ・キャッシング は混ぜて使えないそうです。

ちょこっと試してみました。

まず、Out of Browser。
Visual Studio 2008 + Silverlight Tools 3 beta 1 のウイザードで作った Silverlight アプリなら Properties\AppManifest.xml に <Deployment.ApplicationIdentity> がコメントアウトされた状態で記述済みです。
このコメントをはずしてビルドしてやるだけで Out of Browser 対応アプリの完成。(ShortName、Title、Blurb なんかは適当に)

次にアセンブリ・キャッシング。
これも Silverlight プロジェクトの 「Reduce Xap size by caching framework extension assemblies」 のチェックボックスをオンにしてビルドしてやるだけ。

こうして作ったアプリをローカルにインストールして Out of Browser で起動。
すると起動はするんですが真っ白で何も表示されません。
エラーメッセージも何も表示されません。
ただ真っ白なウインドウがあるだけです。

というわけで Out of Browser を試すときはアセンブリ・キャッシングはオフにしましょう。
# さすがに今後のリリースではビルド時にチェックされるなり、実行時にエラーが表示されるなりするようになると思いますが。


2009年4月20日月曜日

[Silverlight] Silverlight.FX でマウス・ホイール対応にする

Silverlight はそのままではマウスホイールに対応していません。
自分で HTML 上のマウスホイールイベントを捕まえて処理してやる必要があります。
と言っても、HTML に JavaScript でイベントハンドラを書いたりする必要はありません。
Silverlight 内から HTML のイベントにアタッチできるので Silverlight 内で完結できます。
コード例は Silverlight Tip of the Day #23 ? How to Capture the Mouse Wheel Event などにあります。
ただ、このコード例はホイールの値を取り出してるだけで、Getting mouse wheel to vertically scroll a datagrid なんかにも 「で、DataGrid でスクロールしたいんだけど、このあとはどうやったらいいの?」 なんて質問があったりします。それに対して Sergey.Lutay さんが完全に動くコード例を載せてくれていますので、、、

って、あれ?リンク切れてる?
さがしたら見つけたので勝手にリンクしちゃいます。
Sergey.Lutay 氏の SkyDrive です。
WheelCtrlKey_withDG.zip
この例では DataGrid を ScrollIntoView() でスクロールしています。

また、Silverlight DataGrid & ListBox mouse scroll support では ListBox など内部に ScrollViewer を持つものと、DataGrid など IScrollProvider を持つものの両方の例が示されています。
完全に動くサンプルコードもダウンロードできます。
詳しくは見てませんが、かなりきちんと作りこまれてるみたいです。

■ で、やっと本題(^^;
MouseWheel Behavior for Silverlight
↑では Silverlight.FX を使って簡単にマウスホイール対応にできると紹介されています。
ScrollViewer と TextBox のコード例が示されていますが、試してみたところ DataGrid にもちゃんと対応してました。
やったのは↓だけ。

  1. Silverlight のプロジェクトの 「参照の追加」 で Silverlight.FX の binaries\Debug\Silverlight\SilverlightFX.dll を追加する。(もちろん Release でもいいです)
  2. XAML に
    <UserControl ...
        xmlns:fxui="clr-namespace:SilverlightFX.UserInterface;assembly=SilverlightFX"
    を追加。
  3. 同じく XAML の DataGrid のところに
    <data:DataGrid ...>
        <fxui:Interaction.Behaviors>
            <fxui:MouseWheelScroll />
        </fxui:Interaction.Behaviors>
    </data:DataGrid>
    を追加。

ほんとにこれだけでちゃんとマウスホイール対応になりました。
すばらしい。

ちなみに、ちょっと Silverlight.FX のソースを見てみたら以下のようなことをしてました。

IScrollProvider scrollProvider = null;

AutomationPeer automationPeer = FrameworkElementAutomationPeer.CreatePeerForElement(AssociatedObject); if (automationPeer != null) { scrollProvider = (IScrollProvider)automationPeer.GetPattern(PatternInterface.Scroll); }
if (scrollProvider == null) { ScrollViewer scrollViewer = GetChildScrollViewer(AssociatedObject); if (scrollViewer != null) { automationPeer = FrameworkElementAutomationPeer.CreatePeerForElement(scrollViewer); if (automationPeer != null) { scrollProvider = (IScrollProvider)automationPeer.GetPattern(PatternInterface.Scroll); } } }

なるほど、「IScrollProvider を持ってるときはそれを使う。持ってないが ScrollViewer を持ってるときは ScrollViewer の IScrollProvider を使う」 とすることによって IScrollProvider で統一してスクロールできるんですね。

しかし、この Silverlight.FX っておもしろいなぁ。
添付プロパティを応用して外部から機能を拡張したりしてるんですね。
それについての解説は Silverlight Behaviors にあるようです。(読んでませんが)
ちなみに、Silverlight.FX には MouseWheelScroll と同じような感じで MouseTriger とか HoverEffect とかおもしろそうなものがいろいろ入ってます。
他にも Window とか盛りだくさんです。
けど、ドキュメントがみつかりません。ソースコードを読んでいくしかないのかなぁ(^^;
まぁ、まだバージョン 0.1.0.0 ですからね(^^


2009年4月16日木曜日

[.NET] All-In-One Code Framework ってなんぞ?

なんか不思議なものを見つけたので覚え書き
All-In-One Code Framework
2009/4/11 に All-In-One Code Framework ってものがリリースされたそうです。
MSDN Forum サポートチームで codefx という名前だったものとかなんとか。

http://cfx.codeplex.com/Wiki/View.aspx?title=All-In-One%20Code%20Framework%20Examples
こちらがその内容みたいなんですが、

  • C#、VB、ATL、MFC なんかで in-process や out-of-process の COM server や ActiveX control をごにょごにょ
  • C#、C++ で ADO、ADO.NET、LINQ をごにょごにょ
  • VSTO で Outlook、Excel をごにょごにょ、C# で Excel automation をごにょごにょ
  • C++、C# でレガシー DLL をごにょごにょ、C# で P/Invoke をごにょごにょ、他にも C++ で CLR をホストしたりとかいろいろとごにょごにょ
  • C#、C++ で名前付きパイプ、メールスロット、共有メモリ、.NET リモーティング、WM_COPYDATA とかをごにょごにょ
  • C# で WinForm をごによごにょ
  • C# で Windows Hook をごにょごにょ
  • Win32 でスタックオーバーフローやスタック corruption (オーバーランのこと?) をごにょごにょ

なんて感じ。
結局はサンプル集ってことなのかな?よくわからんw


[Live] SkyDrive は Silverlight を使うようになり、Favorite は同期ができるようになる

SkyDrive Adds New Silverlight-Enabled Features より
SkyDrive が Siverlight を使うようになるそうです。
Windows Live の Photo Album (Live Spaces Photo Album とか呼ばれてたやつ) は今は SkyDrive の一部なのでフォトアルバムも Silverlight を使って操作したりできるようになるみたいです。

あと、これまたいつの間にか SkyDrive の一部になっている Favorite (お気に入り) もコンピュータ間で同期ができるようになるみたいです。
ていうか、これ、Windows Live ツールバー (以前は MSN ツールバーって呼ばれてたっけ?) を入れておくと IE のお気に入りを複数の PC 間で同期するってことができてたんですよね。
それが Favorite が SkyDrive に統合された時から動かなくなってました。
これは、便利に使ってたのでかなり残念でした。
それがようやく復活するんですね。

Minor updates to SkyDrive and Sync arrive
こんな記事もありました。
SkyDrive が Silverlight 対応するだけではなく、Windows Live Sync を通じて画像やファイルを複数の PC 間で同期することができるようになるそうです。
Favorite の同期もこれでやるってことなのかな?
というか、Live Mesh と Live Sync ってものすごく被っているような気がするんだが。


[IE] IE プラグイン用マネージドラッパー

IE8 - Managed Code PlugIns より
IE プラグイン用 COM インターフェースのマネージドラッパーがリリースされているそうです。
IE7 と IE8 対応で、Express Edittion も含めた Visual Sutdio 用だそうです。
SpicIE と呼ばれてるそうです。
http://code.msdn.microsoft.com/SpicIE

SpicIE では

  • IE browsing event handlers
  • IE toolbar buttons
  • IE menu entries
  • IE context menu entries
  • IE explorer bars
  • IE toolbars

なんてのが開発できるそうですから、MSDN Library: Browser Extensions にあるようなことは一通りできるみたいですね。
.NET 2.0、3.0、3.5 に対応とのこと。

へぇ、こんなのあったんだ。
こりゃいいな。

ところで、素朴な疑問。
この辺の IE Extensions は基本的にインプロセスの COM だけど、今後 .NET Framework 4.0 が出てきたら 2.0、3.0、3.5 と混ざっても平気なんだっけ?
と、ちょっと気になったので、検索してみたら
CLR 4.0: In Process Side-by-Side CLR Hosting
こんなのを発見。
この記事がなんの資料を元にしているのかがわかりませんが、4.0 では 2.0 と 4.0 の In-Process Side by Side のホスティングがサポートされるようですね。
で、3.0 と 3.5 はランタイムは 2.0 だから 2.0 と 4.0 がホストできれば事足りると。
(1.0 と 1.1 はサポート対象外みたいです)


2009年4月14日火曜日

[Silverlight] Silverlight 3 のローカル・メッセージング

1つのページ上に複数の Silverlight アプリケーションがのっかっている場合、それらが相互に通信する方法は Silverlight 2 までは特に用意されていませんでした。
ただ、通信することが不可能ってわけじゃ無いです。
Silverlight アプリは HTML 上のオブジェクトを操作することができます。JavaScript を呼び出すこともできます。基本的に HTML 上の JavaScript でできることは Silverlight でもできるようになっているわけです。
反対に JavaScript から呼び出し可能なようにプロパティ・メソッドを公開することもできます。
これらを利用すればある Silverlight アプリから別の Silverlight アプリを呼び出すことができます。
呼び出してほしい Silverlight アプリがプロパティ・メソッドを公開しておき、呼び出し元の Silverlight アプリがそれを呼び出してやればいいわけです。
まぁ、通信なんていう高度なものじゃなく、呼び出し元アプリは HMTL 上のオブジェクトを呼び出していると思っているだけ、呼ばれている方は HTML 上の JavaScript か何かから呼ばれていると思っているだけ、ということですが。
もちろん、呼び出すときにマネージドな世界から JavaScript オブジェクトな世界へ、そして、JavaScript オブジェクトな世界からマネージドな世界へとマーシャリングされますし、戻ってくるときにもマネージド→JS→マネージドとマーシャリングされます。
なお、String、DateTime、数値型などは標準でマーシャリングがサポートされていますので問題ありませんが、オリジナルのクラスなどはマーシャリング方法が不明となるため実行時に例外が発生します。
自分でマーシャラを定義したりできればいいんですが、そういった機能はないようです。
私はあきらめて System.Runtime.Serialization.Json.DataContractJsonSerializer クラスを使って JSON 文字列をやり取りするようにしました。

と、前置きが長くなりました。
Silverlight 3 の新機能、ローカル・メッセージングは Silverlight アプリどうしの通信を行うためのものです。
Silverlight 3: What's New with Local Messaging
によると、同じページ上にある Silverlight アプリどうしの通信だけでなく、ブラウザの別のタブ上にあるものや別のブラウザで動いているものとの通信もサポートされるようです。ただし、Silverlight アプリが同じドメイン上にあったものどうしでのみ通信できるようです。セキュリティ的に考えると妥当なところですね。

使い方はとってもシンプルです。
上記の記事にあるサンプルコードを見ればすぐわかるでしょう。
ただ、通信できる内容もシンプルでどうやら String だけの様子。(System.Windows.Messaging.LocalMessageReceiver クラスの MessageReceived イベントに渡されるのが string Message くらいしかない)
任意のオブジェクトを渡せると便利なんだけど、やっぱりそれは自分でシリアライズするなりして何とかしろってことなのか。


2009年4月8日水曜日

[Silverlight] Silverlight 3 のアセンブリ・キャッシング

Silverlight 3's New Assembly Caching
Silverlight 3 のアセンブリ・キャッシングについてまとめられていました。

Silverlight 2 では BCL (ベースクラスライブラリ) の一部ではあるが Silverlight ランタイムに含まれていないようなアセンブリ (たとえば System.Xml.Linq.dll など) も XAP ファイルにいっしょに収められていました。
Silverlight 3 ではこのようなアセンブリを XAP ファイルに含めなくてもよくなったそうです。

上記記事では設定方法についても解説されています。
Visual Studio 2008 のプロジェクトのプロパティにある “Reduce Xap size” チェックボックスをオンにする、必要な操作はこれだけだそうです。
これでリビルドすると XAP ファイルにはコアランタイムの一部とみなされるアセンブリは含まれなくなります。
また、manifest ファイルが自動的に書き換えられ、コアランタイムのダウンロード場所を示す <Deployment.ExternalParts> セクションが作られるそうです。

もちろん、Silverlight は必要なアセンブリが無ければ manifest ファイルを参照してダウンロードします。
ダウンロードしたアセンブリはデフォルトのブラウザキャッシュにキャッシュされるそうです。
もちろん、XAP ファイルもここにキャッシュされています。
このキャッシュは共有されます。
ある Silverlight アプリが System.Xml.Linq.dll をダウンロードしてキャッシュしたら、他のアプリがそれを必要とする場合はそのキャッシュが使いまわされるわけです。

記事の例では 225K あった XAP ファイルが “Reduce Xap size” をオンにしてビルドしたら 12K になったそうです。

なるほどぉ。
これはなかなかいいですね。
いったいどこまでがコアランタイムとみなされるのか、それはいったいどこで判断してるのか、といったところはよくわかりませんが、使うたびに XAP に入るよりはずっとよさそうです。
Silverlight Toolkit のような形でチャートだとか高度な DataGrid だとかといったコントロールが追加でリリースされたりすると思いますが、そういったものも毎回 XAP ファイルに入れる必要がなくなるかも。(というか入れなくて済むようにしてほしいなぁ)


2009年4月6日月曜日

[Silverlight] Virtual Earth Silverlight Map コントロールをぐりぐり動かすデモ

Virtual Earth Silverlight Map Control CTP ? Crazy Spinning Map with Silverlight 3 Beta
Virtual Earth Silverlight Map コントロールと Silverlight 3 の Perspective 3D 機能を組み合わせたデモです。

記事内の “Virtual Earth Silverlight Map Control CTP / Silverlight 3 Crazy Spinning Map Sample” というリンクをクリックすれば実際にデモを実行してみることができます。(もちろん要 Silverlight 3 です)
デモでは、x, y, z それぞれごとにスライダで回転することができます。
また、「>」 ボタンをクリックするとぐるぐる回ります。「||」ボタンで止まります。

まぁ、Virtual Earth Silverlight Map コントロールと Perspective 3D を組み合わせただけですし、だからどうしたと言えばそうなんですが(笑)、やっぱりぐるぐる回りながらも Virtual Earth が普通に操作できるのを見ると 「すげぇ」 と感じました。
ぐるぐる回しながら操作してると酔いそうですがwww


2009年4月3日金曜日

[Silverlight] Silverlight 3 のハードウエア・アクセラレーションについて

Silverlight 3 の新機能、GPU によるハードウエア・アクセラレーションについてです。

Silverlight 3 Quick Tip #4: Hardware Acceleration
Bitmap Caching in Silverlight 3

まず、デフォルトではハードウエア・アクセラレーションは無効になっています。
<object> タグを使っている場合は

<param name="EnableGPUAcceleration" value="true" />

のように EnableGPUAcceleration を指定してやる必要があります。
ASP.NET サーバサイドコントロールの場合は <asp:Silverlight EnableGPUAcceleration=”true” ... />、Silverlight.js の場合は忘れましたが create するところで EnableGPUAcceleration を true にしてやります。

ただし、これだけでハードウエア・アクセラレーションが働くわけではありません。
ハードウエア・アクセラレーションを有効にしてやりたい XAML エレメントに CacheMode=”BitmapCache” を付けてやる必要があります。

<StackPanel CacheMode="BitmapCache"/>

とかっていう感じです。
CacheMode に指定できるのは今のところ BitmapCache のみのようです。
CacheMode が指定された要素、および、その子供たちがハードウエア・アクセラレーションの対象となります。

そもそも、ハードウエア・アクセラレーションが使えるのは

  • Windows: ブラウザ、および、フルスクリーン (DirectX 9.0c 以上が入っている必要あり)
  • Mac: フルスクリーンのときのみ (Safari のフラグイン・モデルの制限から来るらしい)

とのことです。

ただ、すべての処理がアクセラレートされるということはもちろん無く、(少なくとも今の beta では)

  • Transform 族(TranslateTransform、ScaleTransform、RotateTransform など)
  • 矩形クリッピング
  • ブレンディング

の処理でのみハードウエア・アクセラレーションが使われるそうです。
なので、こういった処理をほとんどしていないようなアプリケーションではハードウエア・アクセラレーションは何の効果もありません。
それどころか 「CacheMode を指定する要素はよくよく考えて決める必要がある」 と書かれています。
レンダリングシステムがキャッシュを使うべきかどうかを判断するオーバーヘッドがそれなりにある、また、レンダリングメカニズムはハードウエア・アクセラレーションする要素を描画するごとにアンマネージの中間サーフェスを使って処理するけれどもこれが実際には使われなかったらかなり高価なものにつく、といった感じで説明されています。
だから 「最上位の要素に CacheMode を指定する」 なんてことはしちゃダメで、ハードウエア・アクセラレーションが必要な最も葉側 (leaf-most) の要素にだけ CacheMode を指定すること、とのことです。
どうやら、ヘタに CacheMode を指定するとかえってパフォーマンスを落とすことになりかねないようですね。

あと、確認用の機能として

<param name="EnableCacheVisualization" value="true" />

というのがあります。
これを指定しておくとハードウエア・アクセラレーションが有効になっている要素は普通に、なっていない要素は赤く表示されます。


    2009年4月2日木曜日

    [Silverlight] Navigation Framework

    Silverlight 3 の新機能、Navigation Framework についてわかりやすくまとまってたので覚え書き。
    The Silverlight 3 Navigation Framework

    • 外側の Frame とコンテンツを表す Page で構成される。
    • Page は XAML のファイル名で識別される。
    • Frame クラスの Navigate メソッドで Page を遷移させる。
    • Page の Title 属性がブラウザのキャプションに表示される。
    • Page の遷移は (可能であれば) ブラウザの履歴に自動的に残り、「戻る」 ボタンなどが使える。
      これは Frame の JournalOwnership 属性で挙動を変えることもできる。
    • NavigationService クラスの Navigate メソッドを使えば Page の遷移時に QueryString を渡すこともできる。
      Page の側では this.NavigationContext.QueryString で受け取る。
    • ディープリンク。各 Page へのリンク (XAML のファイル名) はブラウザのアドレスのところに出るのでブックマークしたりできる。
    • UriMapper クラスを使えば各 Page のエイリアスを定義できる。