Ticket #197 (closed 不具合: fixed)

Opened 3 years ago

Last modified 2 years ago

半透明にしたフレームを移動させる際にちらつく/不透明になる

Reported by: gotoh Assigned to: horiguti
Priority: major Milestone: ver 3.00
Component: 画面表示 Version: 3.00 (開発中)
Keywords: Cc:

Description

フレームを半透明にする設定を使用していて、 タイトルバーをつかんでウィンドウを移動させると、 半透明と不透明をちらちらといったりきたりする。

また、ドラッグ中にマウス位置を止めておくとその間、不透明になる。

mw32_update_frame_alpha()の処理が必要以上に呼び出され、 不要な不透明化が実行されているような感じ。 これのせいか、描画処理が若干遅くなる。 特にoverlayの描画処理が顕著に遅くなっているようだ(dired で確認)。

r3904を Windows XPで使用。

Attachments

Change History

2005年10月14日 13時41分47秒 changed by horiguti

  • owner changed from LayeredWindow, alpha to horiguti.
  • status changed from new to assigned.

r3905 で大分よくなっていると思いますがどうでしょうか.

2005年10月15日 02時00分26秒 changed by gotoh

ちらつきかなくなりましたし、不透明にもならなくなりました。 その点では本件は終了ですが、しかし、ものすごい負荷です。 taskmgrで見ていると、ドラッグして移動している最中の meadowの負荷は95%に達しています。 無駄な呼び出しが多発しているような気がしてますが、根拠なしです。

2005年10月15日 02時07分26秒 changed by gotoh

負荷の件ですが、半透明による移動に限らず、(100 80 50)という設定でアクティブな状態 (完全に不透明な状態)で使っている際にも、カーソル移動でさえもかなりの 負荷が発生します。 当然、nilだと負荷は発生しません。

2005年10月15日 17時24分26秒 changed by horiguti

r3916 で余計な SetLayeredWindowAttributes?() の呼び出しを抑制するようにしました.
以前 SetLayeredWindowAttributes?() を呼び出さないと画面の更新が表示されないという状況があったのでこのようにしたのですが, 今試してみたら大丈夫だったので alpha値を変更するとき意外は呼び出すのをやめることにしました.
これでカーソル移動で負荷が上昇することはなくなりました. ただし, ウィンドウの移動は負荷が減っているとはいえLayeredWindow?の移動自体が重いのである程度の負荷にはなるようです.

2005年10月15日 19時54分05秒 changed by gotoh

r3916は試してみたのですが、改善はしているようですが、やはりカーソル移動が以上です。 meadow -q で起動して *scratch*にて (set-frame-parameter (selected-frame) 'alpha '(100 80 50)) として、そのままC-mをキーリピートしてみると、ぎこちなく動きます。負荷も高い。

いまいちどやってみたら、上記式を変更してすぐにキーリピートさせてみたら、 今度は画面が更新されなくなりました。 キー入力は効いているのだが画面が更新されず、別アプリケーションに移ると書き換えが発生して 入力した内容が表示されているという動き。 キー入力で再描画(invalidate)が行われていないようにもみえる。 「alpha値が同じ場合は処理を行わない」というコードで一緒に省かれてたりするのか? これは何度か再現していますが、ちゃんとキー入力が出来たときもあります。

ふしぎー

2005年10月15日 20時30分26秒 changed by horiguti

あぁ.. そういうことですか.. 私は Pen4 HT でやっていたときに同じ症状が出て, それが SetLayeredWindowAttributes?() を画面の兄用が変わるごとに発行するごことできちんと変更が反映されるようになったというのが r3899 のコードです.
r3916 を試したのは PenM 1GHz のノートPCです. これだと書き換えがきちんとリアルタイムに反映されるようです.
本来 Layered Window の処理は CompatibleDC を取得して, それに対して描画したものを UpdateLayeredWindow?() で反映するのが本筋ですが, プログラムを書き換えずに Layerd Window を使えるようにするために SetLayeredWindowAttributes?() があるということらしいですね.

本題はここからで, この場合の書き換えはどうやったら表示に反映されるのかがよくわからないので困っています. なんか知ってますか? もしどうしようもないなら描画系を丸ごと !CompatibleDC を使うようにうまく直してやらなければなりません. もしかすると適当なマクロでごまかせるかもしれませんが..

というわけでとりあえず重くても画面の書き換えがきちんとされるほうがよさそうなので MW32_update_end() で毎度 SetLayeredWindowAttributes?() を呼び出すように戻しますか. 移動中は本当に不要なのでこちらは省くようにします.

2005年10月16日 02時23分18秒 changed by horiguti

なんか同じことをやっているはずなのに動作が変わったりしてさらによくわからなくなってきたのでいくつか試しすことにします.

r3920 では mw32-update-alpha-hint という変数を用意して動作を切り替えるようにしています.
不透明度が変化したら SetLayeredWindowAttributes?() を呼び出します.
そしてmw32-update-alpha-hint の値が,

0. だと不透明度が変化しない限り何もしません.
1. だと移動中以外では不透明度が変化しなくても InvalidateRect?() で全領域を無効化します.
2. だと移動中以外では不透明度が変化しなくても SetLayeredWindowAddtributes?() を呼び出します.

0だとたぶん使い物にならないと思います. 2 と 3 で何か違いは出ますか?

2005年10月16日 10時55分46秒 changed by gotoh

r3920でmw-update-allpha-hintを変えて試してみました。 環境はThinkPad X31 (WinXP)で、alpha設定は(100 80 50)にて。

0だと先に述べたような、alpha値が100でもキー入力で再描画されない症状。

1だとキー入力の問題はなく、100でもカーソル操作や挿入操作などが若干もたつく。 フレーム移動などは高負荷。

2だとキー入力の問題はなく、100でもカーソル操作や挿入操作などがかなーりもたつく。 当然フレーム移動も高負荷。

なので0は論外で、2よりは1の方がましというところ。

ちょっとおもしろいのは、1にせよ2にせよC-fでのカーソルをすると描画がされていない感じ。 最初負荷の問題でキー入力のスピードに追いついていないのかと思っていたけど、 C-nやM-fでは負荷が高いながらもちゃん追従してと描画される。 C-fでもまったく描画されないのではなく、行が変わると描画されるみたい。 つまり、キーリピート中はカーソルは常にどこかの行の先頭に描画される。 またこのときカーソル描画が行われないせいか、負荷は低い。

2005年10月17日 21時08分51秒 changed by horiguti

(set-cursor-type 'box) とかにしていますね?
(set-cursor-type 'caret) だと軽快だし, ほぼちゃんと動きます:-p

先にあげた方法のほかに UpdateWindow?(), GdiFlush?() と試してみましたが, hint=0 で表示が行われない状況ではどちらもだめでした. かとおもったらいつの間にか hint=0 でも普通に使えるようになっていたりと非常に状況が不安定です. リブートしたら一定の状態になるというわけでもないようです.

で, 手許のノートPCでは確かに偽カーソル縦移動はおきます. これが解決のヒントになるのか..
# 結局UpdateLayeredWindow?() を使うと全画面リフレッシュになるのでそうじゃなければ
# SetLayeredWindowAttributes?()を使えと UpdateLayeredWindow?()のドキュメントに書いてありました.

2005年10月17日 21時21分48秒 changed by horiguti

結構長びいてますね..

以下のパッチを xdisp.c に当てるとどうなりますか? 私の手許ではまぁまぁの追従性になっています.

--- xdisp.c	(revision 3922)
+++ xdisp.c	(working copy)
@@ -21084,6 +21084,7 @@
   rif->draw_window_cursor (w, glyph_row, x, y,
 			   new_cursor_type, new_cursor_width,
 			   on, active_cursor);
+  UpdateWindow (FRAME_MW32_WINDOW (f));
 }

2005年10月18日 01時46分15秒 changed by gotoh

試験はいつも meadow -q で行っていますので、cursor-typeはデフォルトのまま。 明示的にcaretにしてみたりboxにしてみたりしましたが、 挙動も負荷もたいして変わりませんでした。 私のところでは、ぎこちなさはcaretの方が強く、boxの方がスムーズに思えます。

xdisp.cのパッチを当てると状況はさらに悪化し、 キーリピートしてたら無応答になってしまいました。 meadow -q で起動して alphaは(100 80 50)にして、カーソルはデフォルトのままで、 ~/.emacsを開いて C-nをキーリピートして画面下に達してスクロールした瞬間、無応答状態に陥ります。 2回再現しています。 その後、起動しただけで最初に1キーも受け付けずに無応答になったこともあり、 それ以降、何度起動してもキー入力/マウス操作を受け付けずに無応答。

その後、xdisp.cのパッチをキャンセルしてビルドしなおして同じことをすると正常に復帰。

r3923 + xdisp.cパッチです。

2005年10月20日 01時16分02秒 changed by horiguti

  • status changed from assigned to closed.
  • resolution set to fixed.

私が試したときは, カーソルの反応がよくなった変わりに2つ目のウィンドウをフレーム内で生成した瞬間に固まりました; 一応ちらつく件は片付いているので, このチケットはclose して, 半透明フレーム内での描画の反応速度が遅いという件で新しいチケットを起こすことにします.

2005年10月20日 11時03分21秒 changed by gotoh

  • milestone set to ver 3.00.

新チケットは #210


Add/Change #197 (半透明にしたフレームを移動させる際にちらつく/不透明になる)




Change Properties
Action