Windows Mobile におけるフォントキャッシュ

QwicTwit の動画を公開した後、ちまちまいじっていたら、特に変なことをした覚えもないのにスクロールが遅くなってしまって立ち往生。原因を探るべく、色々試してた。

  • プロファイリングしてみよう、と思ったら Windows Mobile な DLL プロジェクトに使えるよさげなプロファイラが見つからなくて断念。
  • 仕方がないので、描画周りで手動で GetTickCount() を埋め込みまくってログ吐かせてみるも、 DrawText() が遅いという何の参考にもならない予想通りの結論に。
  • でも文字描画周りは触ってないしなあ。
  • フォントキャッシュ周りの値を変更しても大差ないし…
  • あれ、前のバージョンに戻しても遅い… 環境がマズいかも!
  • と、フォーマットまでしたのにやっぱり遅い。
  • うーん、あの動きは幻覚だったのか…
  • でも動画という証拠が残っていて俺涙目

単純に BitBlt() でスクロールできてしまえば速いけど、背景画像があるからそうもいかない。じゃあ思い切って、オフスクリーンサーフェス + マスクでスプライト作戦か! とか思い立つも、夢のテクノロジー ClearType の前に打ちひしがれる。いや、さすがにここで RGBA のアルファブレンド書くのは違うだろー…とか考えつつ cairo のコードを眺めてみたりもした。さてどうしたものか。結局詰まってしまって何も進まない。

で、今日も今日とて色々試していたわけです。

HKLM\System\GDI\Glyphcache\limit の値をデフォルト (0x400) に戻して、やっぱりデフォルトは遅いんだなぁと実感した後、適当に 128KB とか 1MB とか変えてみたら、どういうわけかキャッシュの効果が頭打ちになる。といっても、キャッシュサイズが巨大すぎて逆に遅くなったりしている、というわけでもなさそう。あと、同じ文字が一画面に多数出てくるような状態だとやたら高速。あれれ、キャッシュの効き方が偏ってる? どんな実装だよ。とか思いつつ MSDN を漁りながらあることに気がついた。

フォントキャッシュは、 DeleteObject(HFONT) した時点で削除される。

毎回律儀にフォントの取得 & 解放してたのをやめたら一気に爆速になって愕然とした。うおー、そんなことどこにも書いてないじゃないか! EUDC (ユーザ定義文字) 周りのドキュメント にちょこっとそれらしいことが書いてるけど直接関係ないし。というか、如何に DrawText() を高速にするか、あるいは呼び出しを減らすか、という点ばかり注視してたので、そもそもフォントキャッシュが効いていなかったなんて予想もしなかった。フォントの取得や解放自体に時間が掛かるわけじゃないから、なおさら気づきにくい。

というわけで、この 3 週間くらい (気が向いた時だけ) 悩んでた問題が解決したので、ようやく前進できそうな感じ。でも結局、動画の時の速さの要因は謎のまま。もちろん動画よりも今の方が速いんだけど、あれは何だったんだろう。

牛歩

研究室行ったら 3 回生の子につきっきりになってしまって、結局自分のことは何も進まず。ありゃりゃ。

SH4 用の kaffe のビルドは色々障壁がありすぎて大変。 1 年前にもやったことなので、今回はそれを生かして・・・と思ってもやることはあまり変わらない。 glibj.zip を使い回して make 時間の短縮を図るぐらい。セルフビルドするには殺人的にメモリが足りない。 (150MB ぐらい要るのに 64MB しかない) まあ、でも、うん、 32MB の頃よりはマシなんだ・・・。
その一方で、クロスコンパイル用に binutils と gcc をビルドしながら、詰まってみたり。ああ、先は長いぞ。
紆余曲折で、 deb の source を色々いじって、 configure のオプション変更して Depends に変更を加えたり直接 make したりする方法を覚えたりした。もしかしたら将来なんかの役に立つかもしれない。

サドルに積雪

帰る頃には雪が吹き荒れておりました。

引きこもり先

今日も今日とて研究室。台数増やしたらうまく動かなかったのでいろいろ調べていたりしたら、こんなページに行き当たりました。

Some JXTA users assume that advertisements must be remote published to another peer in order for the advertisement to be discovered. This is not true!

Don’t Rely on remotePublish() – Pandemonium Medicine Show

うおー、I have misunderstood exactly as you wrote. って感じです。

ようやく光が見えてきましたとかいいながら、その後全力でJXTAの罠にかかる。 remotePublish() は propagate なんかしませんよ、って話。えー、じゃあ publish() と remotePublish() の違いって何だ?と思ったら、remotePublish() and publish() are separate APIs for implementation efficiency reasons only って言い切ってる。うえー。 remotePublish() は、(コード読むかぎり) 一応 RendezVous Service で propagate してるけど、これも 2 hop 以上先には行かない感じ。なんてこったー。

うまくはいかないもんです。

「JXTAのすべて」 ( JXTA に関するほぼ唯一の参考書、でも古すぎて肝心のサンプルソースが参考にならない) の最後のサンプルとして JXTA Messenger とか載ってるけど、この PresenceService のコードは (ver. 2 系列用に rewrite したところで) 期待する動作はしないわけだ。世の中の remotePublish() の勘違いの発端はこのサンプルじゃないのかと問い詰めたい・・・。

そしてここまで書いてから、読んでも誰も分からないことを書いちゃってることに気がつきました。うーん。research (主にひとりごとをつぶやく) タグを付けておくことにします。