Search
Categories
Articles
Rainmeter関連
ファイル置き場
お知り合いなど

スポンサーサイト

--.--.-- | スポンサー広告

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Rainmeter-dev] 負荷を減らす取り組み

2010.12.22 | Rainmeter-dev

0 Comments

Rainmeterもアップデートを繰り返し、バグフィックスだけでなく新規能も多く取り入れられました。特に新機能については、いままで出来なかったことをするためのものなので、当然コードサイズも増えるし、出来上がる実行ファイルのサイズも増えるし、実行時の負荷も(処理内容によっては)増えています。ベタ実装なものも多いので、処理が改善できそうな部分については適宜変更を入れています。

例えば、無駄な一時オブジェクト生成をなくしたり、処理に入る前に前提条件をチェックして必要なければ処理しないようにするとか。前者は1.4 betaに入ってから、コンパイル時に生成されたアセンブラコードをチェックしながらいろいろと洗い出して、大分減らしました。ほとんどが文字列絡みです。dllサイズも結構減りました(その分新規能が追加されて、増えてますが)。

後者については、主にフラグを設置して処理が必要かどうかをチェックしていますが、Rainmeterの場合はいろんなものが動的に変化する可能性があるので、適用できる部分は少ないです。むやみにフラグチェックを入れてしまうと、逆に本来の処理を行うよりも非効率的になってしまうこともあるためです。逆に、処理時間がかかるような部分には積極的に取り入れています(例えば画像処理とか、DynamicVariablesで変更された設定を反映させる処理とか)。

そういう部分と比較しても、まだまだ重い部分があります。Rainmeterで実際に一番重い(遅い)部分はどこでしょうか。
縦横サイズの大きなスキンを使っている人にはわかるかもしれませんが、描画(GDI+)です。

GDI+はいろいろと面倒な描画を簡単に使えるので重宝しますが、描画にかかる時間はGDIでDIBSectionを使った場合に比べると、とても遅いです(DIBSectionについては次回説明)。描画サイズが大きくなるほど、または更新間隔が短くなればなるほど、その差はハッキリと体感できるようになります。
(※Measureが大量にあってMeterは少ない・小さいとか、そういったスキンではこの限りではありません)

GDI+な部分についても、個別のMeterごとに、描画用にキャッシュを使うとか、GraphicsPathを使って一気に描くとか、負荷を減らせそうな変更は適宜入れていますが、表示の互換性も考えないといけないので、大胆には弄れません(オフセット位置が1pxズレるだけで表示結果が変わってしまう)。

ただ、描画について考えるのであれば、RainmeterではUpdate間隔ごとに全Meterをバックバッファに再描画し直していることを考慮すべきです。もし「前回の表示内容から何も変更がない」なら、この再描画処理は本来必要なく、描画済みのバックバッファをそのまま使えます。

「変更がない」ことを確認するには、「全てのMeterの設定・使用するMeasure値が変更されていない」ことを確認すれば、目的を達せられそうです。

続きを読む »

スポンサーサイト

[Rainmeter] スキン作成時に気をつけてること

2010.12.18 | Rainmeter

0 Comments

たまにはスキン作成自体のお話を……と言っても、自分自身ではほとんどスキンを作らないので、凝ったTipsなんてものはありません。プログラムの関係上、ここはこうしたほうが効率的かも~というTipsをいくつか挙げておきたいと思います。「○○しない」と書いてある場合、してはいけないという意味ではなく、できるならそうしないほうがいいという意味で捉えてください。

1) むやみにDynamicWindowSize=1を使わない

DynamicWindowSize=1が設定されていると、Update間隔ごとに全Meterの位置・サイズを計算し直して、ウィンドウのサイズが変わらないかどうかチェックします。もし最初からウィンドウサイズが変わらないようにスキンが設計されているのであれば、この処理は無駄になります。
DynamicWindowSize=1を指定しないとウィンドウサイズは固定のままなのかというと、そういうわけでもなくて、!RainmeterShowMeterやMoveMeterなどのMeterの位置やサイズを弄るbangを使うことで再計算フラグが立ち、必要であればウィンドウサイズが変更されます。ただし、DynamicVariablesを使っていると、bangを使わずにMeterの位置やサイズが変わる可能性があるため、再計算が起こらないと困ることになります。素直にDynamicWindowSize=1を指定しておいたほうがいいでしょう。
余談ですが、アニメーションスキンを作る場合にも、ウィンドウサイズは固定にしておいたほうがいいです。ウィンドウサイズの縮小→拡大→縮小が発生するようなスキンだと、→縮小のときは問題ないのですが、→拡大のときに非常に遅くなります。

2) Backgroundを使わない

BackgroundMode=0と3ではBackground=に指定した画像を背景として扱いますが、それ以外に、「R255,G0,B255」(紫)や透明な領域をクリップする(ウィンドウのリージョンを切って、変形ウィンドウを作る)という処理が入ります。さらにDynamicWindowSize=1が指定されていると、場合によってはこの処理がむちゃくちゃ重くなります(透明不透明が斑模様になるようなスキンとか)。
BackgroundMode=0はウィンドウのサイズを画像サイズに固定、=3では特殊なスケーリングと、代用手段がないものでもありますが、こだわらないならMeter=Imageで代用しちゃってもいいと思います。
(※Rainmeter 1.4 betaには、Meter=ImageにBackgroundMode=3と同じスケーリング機能を追加してあります。BackgroundMarginsと同じように、ScaleMarginsを設定してください)

3) BackgroundMode=2を使わない

BackgroundMode=2は指定色で背景を塗りつぶすモードです。そのためだけにウィンドウサイズ分の画像バッファを作成し、メモリを消費します。必要なサイズが640x480だとすると、約1MBほどの消費です。Meter=ImageでSolidColor=を使って塗りつぶす場合はバッファを作らないので、BackgroundMode=1でMeter=Imageを併用したほうがメモリ消費量を減らせます。
わざわざバッファを用意していた理由はわかりませんが、グラデーション効果を使ったときに多少なりとも負荷がかかるので、毎回描画するよりはバッファに描いて、それを再描画時に使ったほうが軽かったのかもしれません。一応、処理時間もチェックしてみましたが、直接描画とバッファ描画でそれほど変わらないどころか、グラデーションを使わないなら直接描画したほうが速かったので、今は直接やっちゃったほうがいいのかもしれません。
(※Rainmeter 1.4 betaではバッファを作成せずに直接描いて、メモリ消費量を減らす方向に調整しました)

4) Meter=Stringで固定文字列のみを表示するときは、Text=ではなくPrefix=を使う

MeasureNameを設定せず、固定文字列のみを表示するときには、例えばText="blah blah blah"と書くよりは、Prefix="blah blah blah"としたほうが効率的です。Text=は%1などのMeasure値を混ぜたいときのみに使います。
たまにMeasureNameが設定されていて、かつTextに"%1"のみを書いているスキンを見かけますが、無駄な処理が入るので指定しないほうがマシです。

5) SolidColor=はどのMeterでも使える

Meter=Imageでしか使えないと思っている人もいるっぽいので、一応。どのMeterでも矩形塗りつぶしに使えます。StringにActionを設定したいときに、SolidColor=0,0,0,1を設定してよく使います(透明に見える不透明で、当たり判定を付ける)。
分かりやすい色を付ける事で、Meterのサイズをチェックする用途にも使えます。

6) Unicodeを活用する

以前にも書きましたが、スキンファイルの文字コードにはUnicode (BOM付きのUTF-16LE)も使えます。個人的に使う分には問題は起きにくいですが、日本語を含むShift-JISのスキンを他言語版Windows上で動かすと文字化けしてしまいますので、そういった用途ではUnicodeにしてしまいましょう。海外で配布されている欧文スキンでも、たまに日本語版Windowsで動かすと文字化けすることがあります(Gnometer旧バージョンのFeedsに定義されてたSubstituteとか)。多バイト文字を含む場合だけでなく、文字コード上の問題もいろいろと解決してくれるので便利です。
ただ、なんでもかんでもUnicode化すればいいのかというと……文字コードの関係上、Shift-JISで1バイトの文字でもUnicodeでは2バイト使うわけで、ファイルサイズも単純に2倍近くになってしまいます。個人的には、どっちでもいいときはShift-JISのままにしてあります。

 

以下はRainmeterを使う上でやっておくといいかも~な項目です。

1) 使わないスキンファイルは退避させておく

スキンの作成とは関係ありませんが、Rainmeterは起動時やRefreshAll時に、Configsメニュー用のキャッシュ作成や、スキン読み込み用のファイルパスなどを全てキャッシュするために、スキンフォルダ内の全.iniファイルをチェックします。スキンフォルダには最低限のものだけ残して、後は退避させておくと、ほんの少しですがファイル探索処理量とメモリ使用量を減らせます。
同様に、Rainmeter.ini内の無駄なエントリを削除するのも効果がある……ような気がして今まで削ってたんですが、こっちはプログラム上はあまり効果ないかもしれません。気分的にスッキリする程度です。

2) ログは(普段使いでは)オフにしておく

ログ出力を有効にしていると、ログを書き出している間は若干ですがパフォーマンスが下がります。スキン作成時や調査時以外では、ログ出力をオフにしておく(またはログファイルを削除しておく)といいと思います。スキンによってはUpdate毎にエラーが出っぱなしになっていることもあって、資源的にも精神衛生上もよくありません。

 

……もう少しくらいあるかな~と思ってたんですが、少なかったですね。
どれもこれも、「これをすると良くなる!」と断言できるものではないので、いろいろ試してみてください。

[Rainmeter] Rainmeter 1.3

2010.12.15 | Rainmeter

0 Comments

バタバタしているうちにRainmeter 1.3も正式版が出ちゃってました(遅。

できるならば、開発をしながらその都度記事をまとめていけるといいんですが、なにぶんコードを書いてるときはそっちに集中してるし、フォーラムでやりとりしてるときは英語のことで頭がいっぱいだし、他のこともやってるし、Twitterでのつぶやき程度で満足しちゃうしで、にんともかんとも。

今回の更新も、ブログテンプレートを変更して気分転換しつつ書き出そうかーなんていう魂胆です。

さて、1.3では1.2の時と同様に、かなりのバグフィックス・新規能の追加を行いました。時間が経ってて、何をやったか自分でもあまり思い出せないのですが、ピックアップすると、

- コンテキストメニューの変更
- Skin/Measure/MeterにGroup機能を追加
- MouseOverAction/MouseLeaveActionの発動方法を修正(キビキビ動くように)
- WebParserに文字参照のデコード機能を追加

あたりでしょうか。

文字参照のデコード機能は、以前の記事にあるものをベースに、数値文字参照だけでなく実体参照もデコードするように変更したものです。ただし、カスタムプラグインとは違い、1.3を入れただけで解決するというわけではありません。公式に取り込むにあたり、これまでに配布されてきたスキンとの互換性を維持するために、デフォルトではオフになっています。スキン製作者または使用者側で設定を追加して有効にする必要があります。

具体的には、"StringIndex="を指定しているMeasureに、"DecodeCharacterReference=1"を追加します。設定値は1以外に、以下の値が指定できます。

0 : なにもしない (デフォルト動作)
1 : 数値文字参照と実体参照の両方をデコードする
2 : 数値文字参照のみをデコードする
3 : 実体参照のみをデコードする

公式スキンセットであるGnometerでは1を使うように対応されていますので、参考にしてみてください。なお、公開しているカスタムプラグインはそのうち撤去しますので、ご了承ください。

Group機能は以前からどうにかできないかなと思っていた機能でした。スキンファイルの中を覗くと恐ろしいくらいに連なっている!RainmeterShowMeter / !RainmeterHideMeterを見るたびに、これがまとめられたらなーと思ってました。MeterStyleとの併用で、定義も楽になると思います。

同じようにどうにか……と思っていたのが、MouseOverActionとMouseLeaveActionの問題。MouseOverActionはいいとして、MeterのMouseLeaveActionは正常に発動しないことがあるので、[Rainmeter]セクションに書いておく回避策を使ったスキンが多いです。これを本来の「Meterから出たら発動」するように修正しました。正式版での仕様に至るまでには、いろいろと試しては修正を繰り返し……。Buttonでの挙動も修正する必要があるし、今までの使い勝手から違和感のない挙動にする必要もあるしで、かなり大変でしたが、最終的にはそう違和感なく仕上がったはずです。

副産物というわけではありませんが、今までよりも厳密にOver/Leaveを判定するようにしたので、特にMouseLeaveActionの発動がもたつかなくなりました(今までは500ms間隔のタイマーで判定していた)。

 

自分の担当外でもいろいろな機能が追加されました。ToolTip機能やAboutダイアログの修正、新プラグインの追加などなど。さらに次期メジャーリリースではC#で書かれたプラグインが追加されたり、スクリプト機能としてLuaが組み込まれるなど、いろいろと大きな変化がありそうです。反面、Rainmeter自体が太ってきてしまっているため、"ダイエット"もさせつつ、ぼちぼちやっていく予定です。

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。