[過去ログ] 今夜も Wine で乾杯! - 21本目 [無断転載禁止]©2ch.net (1002レス)
1-

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
403: 2018/02/17(土)17:41 ID:KjUUJ1nJ(7/9) AAS
AA省
404: 2018/02/17(土)17:42 ID:KjUUJ1nJ(8/9) AAS
AA省
405: 2018/02/17(土)18:08 ID:KjUUJ1nJ(9/9) AAS
ちなみに、
1. ~/.wine
2. ~/wine

は別物です。1は、binary をインストールした際に出来るデフォルトのフォルダ
ですよね。2. は、git からソースを持ってきた時にできるディレクトリです。

まずは、バイナリをインストールして動作してから、ソースを持ってきてください。
406
(4): 2018/02/17(土)18:27 ID:1JDlaACg(1) AAS
半透明化はWin32API側でどうやっているの? Linuxネイティブなアプリでは?

SetLayeredWindowAttributesであれば、user32.dllからUSER_Driverを介してwinex11.drvが呼ばれて、
window.c内のsync_window_opacityで_NET_WM_WINDOW_OPACITYにα値を設定している様子が見て取れる
外部リンク[c]:github.com

TRACEで表示しているメッセージを確認するには環境変数WINEDEBUGを使って、
WINEDEBUG=win,x11 みたいにカンマ区切りで指定する。細かくは
外部リンク:wiki.winehq.org に書いてある。

あとは、dlls配下の各ディレクトリでもmake && sudo make instlallできるので
特定のDLLファイルしか変更しないのであれば、この方法でビルド時間を短縮できるぞ。
407: 2018/02/17(土)18:42 ID:cvAP0C15(1/2) AAS
デバッグ大変だな。めんどくさそう。
仕事じゃないと俺はやらないだろうな。
408: 2018/02/17(土)19:41 ID:J9G7l4mf(1) AAS
自分はimm32関連(日本語入力)APIを修正しようとeclipceでコンパイル環境作ったはいいけど
ネイティブのウィンドウマネージャ関連の知識不足でソースの意味がわからず寝かせてある・・・
409
(1): 2018/02/17(土)19:54 ID:Tf7u8zkg(1/4) AAS
>>406
Linux Nativeアプリの場合、32BIT COLOR にすると、A,R,G,B の 4つの値を
ドットの「色」として指定できます。Aがα値です。このようなことは、Windows
では出来ないと思います。Windowsの場合、CreateWindowExのdwExStyle に
WS_EX_LAYEREDを指定すると透明、半透明が扱えるようになります。

1.完全に「透明になる色」を24BIT値で1色指定できます。この色で描いたドットは、
 デスクトップまで透けて見えるようになります。見た目だけではなく、Windowメッ
 セージも下のWindowに伝達されてしまうことになりますが。

2.ドットごとではなく、Window全体のα値を1つ(1BYTE)だけ指定できます。
 ドットごとでは無いので、全体的に透明度が決まってしまいます。
省3
410
(1): 2018/02/17(土)19:57 ID:Tf7u8zkg(2/4) AAS
/wine/dlls/winex11.drv/x11drv.h
に次のような構造体があり、この whole_window というのが大事らしい:
/* x11drv private window data */
struct x11drv_win_data {
Display *display; /* display connection for the thread owning the window */
XVisualInfo vis; /* X visual used by this window */
Colormap colormap; /* colormap if non-default visual */
HWND hwnd; /* hwnd that this private data belongs to */
Window whole_window; /* X window for the complete window */
Window client_window; /* X window for the client area */
省21
411: 2018/02/17(土)20:00 ID:Tf7u8zkg(3/4) AAS
>>406
後半の二つ。自分に取っては、かなり貴重な情報です。助かります。
412: 2018/02/17(土)20:11 ID:Tf7u8zkg(4/4) AAS
>>406
XWindow で透明化。これはやってみて実際に出来ました:
外部リンク:stackoverflow.com
how-to-create-semi-transparent-white-window-in-xlib

子ウィンドウを入れてみても、ちゃんと出来ました。

ただし、子ウィンドウには、Win32のような、タイトルバーは付ききませんでした。
XWindow に詳しい人によれば、XWindow の Window Manager は、
Win32 の MDI のような事は、サポートしていないらしいです。絶対か
どうかは分かりませんが。

実験してみると、子ウィンドウも、親ウィンドウも、ABI で、XMoveWindow
省3
413: 2018/02/17(土)21:31 ID:cvAP0C15(2/2) AAS
Win32APIだけじゃなく、X Windowについても知っておかないといけないのか
面倒臭っ・・・

普段使ってるだけでずいぶん楽してたんだな。
414: 2018/02/17(土)22:08 ID:eqmjcJnH(2/2) AAS
面白そうだけど時間ねえな……
>>410を見る限りだとuse_alphaは持ってるけどAlpha値自体はもうX11の構造体にいれてるのかな?
まあ遅くなる理由とか検討つかんけど……
415
(3): 396 2018/02/18(日)01:13 ID:DznsC7ZZ(1) AAS
WINEにおいて、

1. MDIのCMDIChildWndのCViewのCLIENT領域全体(子ウィンドウの
  中全体と言ってもよい) に >>409の1.の色を塗って、完全透明
  にしている時は、CMDIChildWndのタイトルバー(子ウィンドウの
  タイトルバー)をドラッグしても高速に動かせる。

2. 1のCViewの中に、pDC->LineTo()で直線を一本描いた状態にしてから
  同じ事をしようとすると、とても遅くなる。

3. 2.は、直線の代わりに pDC->TextOut() で文字を描いても同様に遅く
  なる。

4. 推定では、Wineは、Win32のCreateWindow系で、Parent Window が
省11
416
(1): 2018/02/18(日)01:24 ID:smHwezpH(1) AAS
推定じゃなくて直接聞いたら?
417: 2018/02/18(日)01:56 ID:HH6qVqdM(1/9) AAS
>>416
どうやって?
418
(3): 406 2018/02/18(日)02:29 ID:dARugMLm(1/2) AAS
>>415
すまん、ウィンドウの半透明化処理(LWA_ALPHA)と勘違いしてた。
ウィンドウ領域内の特定色で書いた箇所を透過させる場合(LWA_COLORKEY)ね。

ソースを調べたら、WineではX11のShape Extensionを使ってウィンドウの形状を変更することで、
「見た目だけではなく、Windowメッセージも下のWindowに伝達すること」を実現しているようだ。

具体的にはupdate_surface_region()で1ピクセルごとにピクセル値を比較して、
XShapeCombineRectanglesに指定する矩形領域を作っている。
外部リンク[c]:github.com

415の2.,3.の条件だと遅くなるとすると、ピクセル値を比較する処理は1.と同じなので、
矩形が大量になったときに、X側で描画性能が低下するのではないかと思うぞ。
省1
419: 2018/02/18(日)04:20 ID:HH6qVqdM(2/9) AAS
>>418
なるほど。

1つ質問です。

はっきりとは書いてなかったのですが、>>415の遅くなる条件であるところの 2,3 の場合
においても、CMainFrame、つまり、アプリケーション全体の Main の Window のタイトルバーを
ドラッグした場合は、遅くなりません。いたって高速にドラッグできます。

>>418 が正しいなら、どうして、X は、この場合だけは速く、CMDIChildWnd の場合だけは
遅く動作するのでしょうか???
420
(1): 2018/02/18(日)04:57 ID:HH6qVqdM(3/9) AAS
AA省
421: 2018/02/18(日)05:32 ID:HH6qVqdM(4/9) AAS
/wine/dlls/user32/painting.c の中の、
// Set the visible region and X11 drawable for the DC associated to a given window.
static void update_visible_region( struct dce *dce )
の中に、
USER_Driver->pGetDC( dce->hdc, dce->hwnd, top_win, &win_rect, &top_rect, flags );
とあって、
void CDECL X11DRV_GetDC( HDC hdc, HWND hwnd, HWND top, const RECT *win_rect,
const RECT *top_rect, DWORD flags )
が呼び出される。引数に hwnd と top、win_rect と top_rect が対になっているらしいことに注意。

この関数の中で、x11drv_escape_set_drawable escape; の
省17
422
(1): 2018/02/18(日)12:58 ID:HH6qVqdM(5/9) AAS
結論的には、Wine では、完全透明色が設定されている全ての LAYERED_WINDOW に
対して、Idle状態の時か、または、50(ms) 毎に、Windowアプリのメッセージループ
の中から自動的に、>>418 の update_surface_region() が呼び出されるようになっ
ているらしいです。この条件のWindowがあって、かつ、update_surface_region() の
処理が重い場合に、動作が遅くなる可能性が高いです。Dirty Bitのようなものは、
今のところ見つかっていませんので、何もしなくても常に重くなるのでしょうか。

【詳細】
flush_window_surfaces() なる関数が、定期的に呼び出される。
典型的なタイミングは、PeekMessage() の中からであり、GetMessage()では、
check_for_driver_events() を介して呼び出される。
省16
423: 396=422 2018/02/18(日)13:53 ID:HH6qVqdM(6/9) AAS
該当の条件の時、新たには何の描画もしていない静止状態でも、Linuxのシステム・モニターで
CPUパワーが膨大に消費されていることを確認しました。このことは、>>422 を裏付ける物です。
だとすると、Dirty Bit を導入して、update_surface_region()の頻度を下げれば、この低速化
は修正できる可能性が出てきました。LineTo, TextOut, MoveWindow, SetWindowPos,
ShowWindow などを使ったときだけ、DirtyBit を 1にして、1の時だけ update_surface_region()
を呼び出し、呼び出した後には 0 にすれば良いのではないかということです。

条件は:

1. WINEを使用して Windowsアプリを走らせていること。
2. アプリ内で CreateWindowEx() のdwExStyle に WS_EX_LAYERED を指定して Windowを作成
  済みであること。
省9
424: 396 2018/02/18(日)14:19 ID:HH6qVqdM(7/9) AAS
>>418 さんの指摘は凄く役立ちました。有難うございます。

ただし、こっちの調査不足のせいが大きいのでしょうが、以下の部分は、今回の
結果とは違っていたようです:
>415の2.,3.の条件だと遅くなるとすると、ピクセル値を比較する処理は1.と同じなので、
>矩形が大量になったときに、X側で描画性能が低下するのではないかと思うぞ。

「X側の描画性能の低下」が原因ではなく、「ピクセル値を比較する処理」自体が、
実は「静止状態」でも、常時、大幅に増加していた、ということです。

何の変化がないときにでも、百万ピクセルを比較し、ランレングスを導き出す処理を、
原則的には秒間20回もやっています。

また、図形が複雑だと、システムコールを呼び出す回数がランレングスの変化の回数倍
省7
425
(2): 396 2018/02/18(日)14:38 ID:HH6qVqdM(8/9) AAS
【厳密化】

1. 多分、6,000回ではなく、4,500回程度でした。
2. 比較処理自体は、図形の複雑さとは無関係にほぼ一定の重さです。
3. 図形が複雑な場合、システムコールの回数が増えます。
4. 横方向の1つのランレングスで、3つのシステムコールが呼ばれます。
5. 図形が何も描かれていない場合、1つのy座標に対して、1つのランレングスです。
6. N 本の直線の場合、大体で言えば、3N 個のランレングスになります。
7. だから、1つのy座標に対し、9N 個のシステムコールが呼ばれることになります。
8. 縦 500 ドットの場合、500*9N = 4500 N 回のシステムコールとなります。
9. よって、中に描かれている直線の本数が増えると、大体 O(N) で処理時間が
省2
426: 396 2018/02/18(日)15:25 ID:HH6qVqdM(9/9) AAS
>>425
【訂正】
「6.」のランレングスの個数は、3N個ではなく、2N+1 個でした。

お騒がせしました。
427
(2): 2018/02/18(日)16:08 ID:dARugMLm(2/2) AAS
>>425
update_surface_regionの方が効率悪そうなので、X側の描画性能が原因と推測した部分は撤回する。

Shape Extensionの仕様を見ると、
矩形領域ではなくマスク用のPixmapを指定する方法も採れるから、
BitBltで効率よくマスクを作ればそっちの方が早くなるかもと思ってみたり。

あと、MDIウィンドウがXのWindowではないことは、xwininfoコマンドの結果でも確認できる。
428
(1): 396 2018/02/18(日)17:01 ID:hqeoLLBF(1) AAS
>>427
>矩形領域ではなくマスク用のPixmapを指定する方法も採れるから、
>BitBltで効率よくマスクを作ればそっちの方が早くなるかもと思ってみたり。

少なくともその方法だと、図形の複雑さによらずに安定して同じ処理時間で
済みますね。それと当然、BitBlt はハードウェアの補助が得られます。
あと、システムコールも全体で数回しか呼ばなて済みますし。
429: 396 2018/02/19(月)12:40 ID:v4nZjJQ1(1/2) AAS
特定のアプリの場合にだけは、自作の user32.dll.so を読み込ませる事が出来ない。
WINEDLLPATH, WINEPATH を試してみたが、今のところ上手く行かない。
430: 396 2018/02/19(月)15:28 ID:v4nZjJQ1(2/2) AAS
調べてみると、/wine/libs/wine/loader.c の中の build_dll_path()
関数の中で、環境変数 WINEDLLPATH が、読み取られ、: を 0x00に
変えてから、dll_paths[] 配列に : で区切られたそれぞれの文字列
の先頭アドレスを代入している。

しかし、その処理に入る前に、get_dlldir() 関数が NULL 以外を返した場合、
dll_paths[0] にその関数が返した文字列のアドレスを入れてしまう。

そして、実際の get_dlldir() は、"/usr/local/bin/../lib/wine"
という文字列を返してくるので、そっちのパスの方が、WINEDLLPATH
の優先順位よりも上になってしまう。そして、

/* retrieve the default dll dir */
省10
431: 2018/02/19(月)15:47 ID:qkc2SRTD(1) AAS
見つかりました。wine/libs/wine/Makefileの中で、
config_EXTRADEFS = \
  -DBINDIR='"${bindir}"' \
  -DDLLDIR='"${dlldir}"' \
  -DLIB_TO_BINDIR=\"`$(MAKEDEP) -R ${libdir} ${bindir}`\" \
  -DLIB_TO_DLLDIR=\"`$(MAKEDEP) -R ${libdir} ${dlldir}`\" \
  -DBIN_TO_DLLDIR=\"`$(MAKEDEP) -R ${bindir} ${dlldir}`\" \
  -DBIN_TO_DATADIR=\"`$(MAKEDEP) -R ${bindir} ${datadir}/wine`\"
というのが。単語検索していたのが鬼門でした。
432: 396 2018/02/19(月)19:22 ID:WuPPo4Ry(1) AAS
loader.c の build_dll_path() の修正と、user32.dll.so の修正を、
自分のアプリだけに適用する事に成功しました。
433
(1): 396 2018/02/20(火)03:10 ID:nCkYsCc8(1/4) AAS
surface が NULL ではない場合、xxx->pLineTo() は、X11DRV_LineTo()
ではなく、dibdrv_LineTo() が呼び出されるような・・・。
434: 396 2018/02/20(火)05:59 ID:nCkYsCc8(2/4) AAS
DirtyBit を使って、例の update_surface_region() は、
描画してないときには全く呼ばれないようにできたんですが、
まだかなり遅いです。何もしてないときにも CPU パワーがかなり消費されています。
その間、update_surface_region() が呼び出されていないことは、FIXME で
表示して確認が取れています。

なお、>>433は、windrv_LineTo() の方の間違いでした。windrv_LineTo() の場合、
簡単に surface にアクセスできるので、surface に bNeedToUpdate のような
フラグを追加して、それを 1 にして dirty bit にしています。

なぜ遅いままなのかは謎です。
435: 2018/02/20(火)06:05 ID:AmaI1OSV(1) AAS
2ch(5ch?)は人は多いけど基本的にユーザーレベルの人ばかりだから技術的な書き込みしても反応は鈍いね
Qiitaにでも書いてみたらどう?
436
(1): 2018/02/20(火)18:28 ID:QMmYbOOf(1) AAS
本家にパッチ投稿もお願いしますw
437: 396 2018/02/20(火)18:49 ID:nCkYsCc8(3/4) AAS
遅い原因の1つは、Onldle の中にあることが分かりました。

1. 必要があって、外部ツールによるファイルの更新チェックをしていたところ、
  それがとんでもなく重い事が判明。

2. SetTimer で CMainFrame にタイマーをしかけていると、CMainFrame::OnCmdMsg()
  が、WM_TIMER メッセージが来る度に、それを何倍にも掛け算した回数だけ呼び
  出される事が判明。例えば、秒間 N 回のタイマーを仕掛けると、OnCmdMsg が、
  10*N 回 呼び出されるような感じです。タイマーメッセージがくる度に、
  メニューなどを更新するためのメッセージが来ているような気がします。
  多分、本家 Windows では、タイマーメッセージが来ても、そのような事には
  ならないんじゃないかと思います。 通常、OnCmdMsg は頻度が低いことが
省7
438
(1): 2018/02/20(火)18:56 ID:nCkYsCc8(4/4) AAS
>>436
そうしたいんですが、何かと大変なんです。

1. メールアドレスの登録するのが、Linuxからだと大変。
2. git の仕様が良く分からない。
3. 回線が遅いので、Project を Fork して、git が Tree 全体を
 アップロードしようとしてしまったりなんかすると大変な事になる。
4. だから、一部のファイルだけを UL したいが、コミュニケーションの
 問題から事情を伝えて、そこまで行くかどうか分からない。
5. だから、独自にオーバーライドしようとしたのが、先日からここでも
 書いていたことです。loader を修正して、かつ、環境変数を変えて
省1
439
(1): 2018/02/20(火)18:59 ID:TT83z4l8(1) AAS
>>438
githubからでもプルリクエスト受け付けてるよ
440: 2018/02/20(火)19:09 ID:LN/W3cN7(1) AAS
先に外部リンク:bugs.winehq.orgに書いた方がいい
報告してあるとパッチ送る時説明が楽になるから
441: 2018/02/20(火)19:12 ID:hMkWg0ue(1) AAS
描画が早くなるならありがたい
素のWindowsより異様に遅いゲームとかあるし
442: 396 2018/02/20(火)20:06 ID:ErFPSqeX(1) AAS
結論だけ書いておくと、surfaceが非NULLの時の LineTo の実体は、
windrv_LineToで、surface を lock する以外は、dibdrv_LineTo と同じ。
dibdrv_LineToは、bits なるpixel配列に 32BITの色値を書き込む。
実際は汎用性のため、必ずandしてからxorする。SOLIDモードの場合、and値は0。
xor値は、00RRGGBB で、最上位バイトは0。
実際への画面の反映は、定期的に「xxx->flush」なる関数ポインタを介して、
x11drv_surface_flush() を呼び出す事で行う。その中で、議題になっている
update_surface_region() も呼ばれる。最後に bits の内容を実画面に反映させる
ため、XShmPutImage()または、XPutImage(), XFlush()を行う。

surface->image の pixel バッファは、bits[] 配列と共通らしい。
省2
443
(1): 396 2018/02/21(水)16:48 ID:SJPTXnf1(1/13) AAS
update_surface_region() が遅いんだと思って、
XShape の作成を、XShapeCombineRectangles() を使う方式から、
XCreateBitmapFromData() と XShapeCombineMask()
を使う方式へと変えた。

すると、1146 x 745 のサイズの Window で、

1. 自前のコードによる 1bit の mask bitmap 作成にかかる時間 :
796 (us)

2. XCreateBitmapFromData() と XShapeCombineMask() にかかる時間 :
38 (us)

3. XShmPutImage() と XFlush() ; x11drv_surface_flush()内 の両方にかかる時間 :
省10
444: 2018/02/21(水)17:03 ID:SJPTXnf1(2/13) AAS
XSync() を追加しても、XShmPutImage() を XPutImage() に修正しても、
何をやっても見た目だけが更新されない。
445
(1): 2018/02/21(水)17:09 ID:iuEniYB2(1/5) AAS
>>443

> update_surface_region() が遅いんだと思って、
> XShape の作成を、XShapeCombineRectangles() を使う方式から、
> XCreateBitmapFromData() と XShapeCombineMask()
> を使う方式へと変えた。

こうするとなんで速くなるの?
446: 396 2018/02/21(水)17:35 ID:SJPTXnf1(3/13) AAS
>>445
それは、
>>427-428
の部分と深く関係しています。
447
(1): 2018/02/21(水)17:39 ID:SJPTXnf1(4/13) AAS
X の同期の問題ではなく、MDI Child Wnd の TITLE BAR をドラッグするとき、
なぜか、数秒経ってから、x11drv_surface_flush() がまとめて何十回も呼び出されている
可能性があるかも・・・。

デバッグ表示をリアルタイムで見ていると、見た目が変化する直前までデバッグ表示が
全く出ず、見た目が変化する直前に、どどっと、数十回分の x11drv_surface_flush()
がまとめて出てくる、という現象が起きている。
448
(1): 2018/02/21(水)17:56 ID:iuEniYB2(2/5) AAS
>>447
flushしてないだけではなく?
449
(2): 396 2018/02/21(水)17:57 ID:SJPTXnf1(5/13) AAS
AA省
450
(1): 396 2018/02/21(水)17:58 ID:SJPTXnf1(6/13) AAS
AA省
451: 396 2018/02/21(水)18:24 ID:SJPTXnf1(7/13) AAS
>>448
PeekMessage()を回しているだけの時で、メッセージがキューに残り続けている場合、
メッセージを 200回 (100回?) PeekMessage するまでは、flush_window_surfaces()
されないコードになっている気がしませんか・・・。
452: 2018/02/21(水)18:32 ID:SJPTXnf1(8/13) AAS
GetMessage() の方もほぼ同じような感じかも。。

とにかく、flush_window_surfaces() がとてつもなく長い間、呼ばれないことが
あるコードになっている様に見えて、実際、実験してもそう思える。
453: 2018/02/21(水)18:38 ID:SJPTXnf1(9/13) AAS
そうか、もともとは、dirty bit 方式じゃないから、flush_window_surfaces() を呼ぶと、
再計算する必要が無いのに必ず再計算されてしまうから、呼び出す頻度を下げるしか
高速化する方法が無いために、そんな風なコードになっているのかもしれない。
454: 2018/02/21(水)18:41 ID:SJPTXnf1(10/13) AAS
そして、flush_window_surfaces() のコードでは、最低でも 50 (ms) の時間が経っていない場合には
処理をスキップするコードになっている。とことん、flush() しないコードになってしまっている。
これらが原因か・・・。

void flush_window_surfaces( BOOL idle )
{
  static DWORD last_idle;
  DWORD now;
  struct window_surface *surface;

  EnterCriticalSection( &surfaces_section );
  now = GetTickCount();
省8
455
(1): 396 2018/02/21(水)18:58 ID:SJPTXnf1(11/13) AAS
元々の Windows では、LineTo などを実行すると瞬間的に実画面に反映される。
だから、そもそも Flush せずに見えないままの描画が残っているなんて時間は
ほぼ 0。

そう考えると、。Wine のこの実装はおかしいな・・・。

1. そもそもメッセージループを回している時しか flush される可能性が全くない
  実装になってしまっているらしい。

2. メッセージループを回していても、メッセージがキューに残っている時は、
  100回程度メッセージを読まない限り、flush されない。

Windows を「エミュレート」するのであれば、例えば、描いてから 50(ms) 経てば、
必ず flush する、という実装でなくてはならないはず。
省1
456: 2018/02/21(水)19:03 ID:SJPTXnf1(12/13) AAS
1. Windows (もちろん、NT系) の場合は、メッセージ・ループ長く帰ってこないプログラムも
 絶対ダメというわけではない。

2. そういうプログラムの場合、Wine 側は、描画を、一定時間間隔で、別スレッドの
  タイマー割り込みの中などで flush するようにしないと、 正しく、Emulation 出来
  ないはず。
457: 2018/02/21(水)19:05 ID:SJPTXnf1(13/13) AAS
割り込みなら、別スレッドを起こす必要が無かった。スマソ。

あと、誤字訂正:
誤: メッセージ・ループ長く帰ってこないプログラムも
正: メッセージ・ループに長く帰ってこないプログラムも
458: 2018/02/21(水)19:13 ID:iuEniYB2(3/5) AAS
うーん
これがボトルネックになっているようには見えない

申し訳ないんだけど描画が遅くなる条件をもう一度書いてもらっていいですか?
459: 396 2018/02/21(水)23:23 ID:4g3iPm6d(1/2) AAS
うーんと。それはまあちょっと置いておいて、、、。

MDI Child Wnd の TITLE BAR を Drag している最中、メッセージループは一つも
回ってないんじゃないかと思う。

だから、>>455 の「1.」に書いた「flushされる必要条件」が満たされてない。

そのため、surface の pixel配列の内容が実画面に反映されないのではなかろうか。
460: 396 2018/02/21(水)23:38 ID:4g3iPm6d(2/2) AAS
ドラッグ中にマウスを静止させてしばらく待っていると、 x11drv_surface_flush() と
flush_surface_region() の両方が呼び出された事が FIXME 出力で確認できた。
静止させずにマウスをドラッグし続けると、FIXME 出力が全くでない。
しかも、それを行った時間が長いと、マウスボタンを離した後も、非常に長い間
システム全体がハングアップした様な状態になる。そして、長い沈黙の後、FIXME出力が
出る。

この沈黙の時間は、それまでドラッグしていた時間に比例しているように思える。

なぜだろう??? これはどこかに「何かが溜まっている」時の現象の様に思える。
しかし、>>449 を見ると、message_cnt は、減らされるときは、一期に 0 になるのであって、
少しずつ減らされるわけではない。
省1
461: 2018/02/21(水)23:42 ID:iuEniYB2(4/5) AAS
単にイベントを送信する側でバッファリングしてるんじゃないの?
462: 2018/02/21(水)23:50 ID:iuEniYB2(5/5) AAS
まあ最初からマルチスレッド意識して書いた感じではないなと思うけど90年代から開発されてるわけだしそのへんはご愛嬌じゃない
463: 396 2018/02/22(木)00:35 ID:9+xI5ulA(1/17) AAS
AA省
464: 396 2018/02/22(木)00:45 ID:9+xI5ulA(2/17) AAS
あるいは、Peek されるだけで、一部のメッセージは取り残されるなら・・・。
465
(1): 396 2018/02/22(木)01:30 ID:9+xI5ulA(3/17) AAS
Wine で、MDI Child Wnd の TITLE BAR をドラッグしたときの処理について。

DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
-->case WM_NCLBUTTONDOWN
-->NC_HandleNCLButtonDown()
-->case HTCAPTION
-->SendMessageW( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam )
-->DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
-->case WM_SYSCOMMAND
-->NC_HandleSysCommand()
-->WINPOS_SysCommandSizeMove()
省15
466
(1): 396 2018/02/22(木)01:32 ID:9+xI5ulA(4/17) AAS
さらに次のような、枠だけを書くか、実際に動かしてしまうコードが続く :

if (!DragFullWindows)
draw_moving_frame( parent, hdc, &sizingRect, thickframe );
else {
RECT rect = sizingRect;
MapWindowPoints( 0, parent, (POINT *)&rect, 2 );
SetWindowPos( hwnd, 0, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top,
( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
}
467: 396 2018/02/22(木)02:01 ID:9+xI5ulA(5/17) AAS
あー。

FIXMEを消してしまっていただけだった・・・。

update_surface_region() や、flush_window_surfaces() は、
ドラッグ中でも、マウスを静止してしばらくすると呼ばれるようです。
マウスを動かしつづけていると呼ばれないらしい。
468
(2): 396 2018/02/22(木)02:44 ID:9+xI5ulA(6/17) AAS
【やっと原因判明】

CMainFrame を WS_EX_LAYERED で透明化していて、今回の条件に当てはまる時に、
CMDIClientWnd のタイトルバー上でマウスの左ボタンを押し始め、そのまま
マウスをずっと動かし続けると、WINPOS_SysCommandSizeMove() の中の

if (!GetMessageW( &msg, 0, 0, 0 )) break;

の部分の GetMessageW() 関数の中で停止してしまう。詳細は、GetMessageW() の
中で、メッセージキューが空だった場合に呼び出されるところの、

wait_objects()    ;dlls/user32/message.c
-->wow_handlers.wait_message()
-->wait_message()  ;dll/user32/winproc.c
省5
469
(1): 396 2018/02/22(木)10:45 ID:9+xI5ulA(7/17) AAS
AA省
470: 396 2018/02/22(木)10:46 ID:9+xI5ulA(8/17) AAS
【通常時、WM_MOUSEMOVE がキューへ追加される時の実行経路】

X11DRV_MsgWaitForMultipleObjectsEx()
--> process_events()
---> call_event_handler( Display *display, XEvent *event )
---> handlers[event->type]( hwnd, event );
event->type = MotionNotify (6)
---> X11DRV_MotionNotify( HWND hwnd, XEvent *xev )
XMotionEvent *event = &xev->xmotion;
INPUT input;
---> send_mouse_input( hwnd, event->window, event->state, &input );
省21
471: 396 2018/02/22(木)10:47 ID:9+xI5ulA(9/17) AAS
AA省
472: 2018/02/22(木)15:16 ID:9+xI5ulA(10/17) AAS
頭に Msg が付かない方の WaitForMultipleObjecstEx() も
挙動がおかしい。 timeout に 0 を指定しても、無限に
待機してしまうことがある。
473: 396 2018/02/22(木)16:31 ID:9+xI5ulA(11/17) AAS
Msg が付く方の WaitXxxx で、usleep() で、0.3秒ほど停止しながら、
Polling (Loop) するようにしてから、FIXMEでメッセージを観察してみた。
普段は、usleep() 命令は、呼び出してから 0.3 秒で戻ってくる。
ところが、先日からの遅くなる条件でドラッグし続けた場合、単純な usleep() の
1命令が、呼び出してから、永久に戻ってこなくなる。ドラッグをやめると、
人間が長く感じるほどの長い時間が経過してから戻ってくる。

これは、WINEの問題ではなく、Linux Kernel の問題だろうか???
474: 396 2018/02/22(木)16:45 ID:9+xI5ulA(12/17) AAS
AA省
475: 396 2018/02/22(木)17:29 ID:9+xI5ulA(13/17) AAS
かなり色々やったつもりだけど、ちょっとこれ以上深入りは難しいので、もう諦めようかも。
以下の上京からするとLinuxカーネルの問題かも知れない:

1. タスクバーも操作不能になる。
2. 単純な usleep() も無限に帰ってこない。
476: 396 2018/02/22(木)17:39 ID:9+xI5ulA(14/17) AAS
Wineでは、昔の MSDN Library の CD もインストールは出来ただが見られなかった。
hh.exe が xxx.COL ファイルを開けないと言ってくる。
yyy.CHM ファイルは、開くことはできたが、右のペーンだけが見えて、左側の目次や
検索のぺーンには何も表示されない。

今回 WINEのソースを見て思うのは、意外とちゃんと書かれていないということ。
MsgWaitXxxx にも、戻り値が明らかに間違っている部分を発見した。
また、TRUE (1)を引数に渡す必要があるところで、1ではない非0 の値を渡している
箇所も見つかった。そのようなコードは後々問題を来すかも知れない。
それに、MsgWaitXxx もちゃんと書かれていない。同時に待機するのは、アプリ・プログラマ
がどんだけ頑張ってもかけないから API が用意されているのだが、そこに明らかな
省3
477: 396 2018/02/22(木)18:45 ID:9+xI5ulA(15/17) AAS
usleep() の部分を setitimer(), pause() に変えてみたら、そこは指定した
時間でちゃんと帰ってくるようになった。でも、Linux全体が停止に近い状態に
なる症状は変わらない。端末内の FIXME の表示が途中の文字まで書かれた状態で
改行までいく前に長い間停止する現象が起きてしまっている。
478: 396 2018/02/22(木)23:32 ID:9+xI5ulA(16/17) AAS
X Window System は、Server と Client で通信を行っているから、Client側では処理が
一瞬で帰って来ているように見えても、Server側では処理に凄く時間がかかっている可能性
があるかもしれない。だから Client側で、関数の呼び出しの前後の時間を計測をしても
それは単にServer にコマンドを送る処理の時間を計測しているに過ぎないのかも
知れない。イメージのバイト数が多いいときには、通信時のデータ・コピーに時間がかかる
から多少時間がかかるかも知れないが、それはまだ表面上の時間に過ぎず、Server 側は
Shapeのくり抜き処理(?)や重ね合わせの処理に膨大な時間がかかっている可能性も否定できない。

だから、XCreateBitmapFromData(), XShapeCombineMask(), XPutImage() の前後の時間を
計測しているだけでは速く見えても、見えない場所でCPUパワーを全開にしてがんばっても
まだ処理を終えてないのかもしれない。
省5
479: 396 2018/02/22(木)23:41 ID:9+xI5ulA(17/17) AAS
そういえば、update_surface_region() が呼び出されたことを示すデバッグ文字列は、後からまとめて
ドドッと出てくる。それは、文字列が「出てない」間には関数が呼ばれてないことを意味する
訳ではなく、実は呼ばれてはいるが、文字列が flush されてないか、または、flush
されていても、端末に CPU リソースが割り当てられないから、文字表示だけが行われずに
文字列がバッファに溜まった状態になってしまっている・・・・。

こう考えれば辻褄が合うかも。
480: 396 2018/02/23(金)00:00 ID:rGoiNTvu(1/9) AAS
本家の Windowsでは、描画処理が重いときには、OnPaint や OnDraw の関数が終わるまで
の時間も長い。だから、メッセージがたくさんたまっているのに描画が追いついていない事は、
メッセージ・キューに残っているメッセージの個数が多い事で大体の判断が付く。だから、
InvalidateRect(NULL)をしておけば、描画が追いついてない場合は、メッセージループ
が WM_PAINTメッセージを送るタイミングを自動的に後回しにしてくれる。

ところが、X Window System の場合、実際の描画がまだ終わってない場合でも、
「描画関数」自体は一瞬にして戻ってきてしまうから、上記のアルゴリズムが「勘違い」を
起こしてしまうことがある・・・。

そらに悪い事に、WINEが、内部で Surface を持っているときには、LineTo 関数自体は高速に
処理を終えるのに、アプリが予想もしないタイミングで、時間の掛かる flush の処理が行われ
省7
481: 396 2018/02/23(金)00:09 ID:rGoiNTvu(2/9) AAS
さらに、>>465-466 >>468 に書いた、WINPOS_SysCommandSizeMove() は、
CWinApp などとは別の、独自のメッセージループを持っている。
そこでは、さらに、WM_PAINT が不適切に大量に発生してしまっている
可能性がある。

だんだん分かってきたかも。
482: 396 2018/02/23(金)00:23 ID:rGoiNTvu(3/9) AAS
原因は推定できてきたけど、さて、どうやってこれを解決すればいいか・・・。
483
(1): 2018/02/23(金)09:55 ID:o5jNB0tx(1/6) AAS
ライセンスの関係でややこしいことに成る可能性が存在するから
5chへソースコードは書かないで
github使ったほうがいい
484: 2018/02/23(金)10:10 ID:53V98ywt(1) AAS
粒度の低いパッチをちょこちょこアップすると良いのでは。
論理値のあやまりを直すやつとか。
485
(1): 396 2018/02/23(金)12:30 ID:rGoiNTvu(4/9) AAS
>>483
それでは、日本人の自分に取って手も足もでない状況になってしまうので、とても
困ります。
486
(2): 2018/02/23(金)12:34 ID:o5jNB0tx(2/6) AAS
>>485
なぜ?
ココに書けば問題が生じる可能性もあるのに
487: 396 2018/02/23(金)12:36 ID:rGoiNTvu(5/9) AAS
協力しにくくしにくくなるように仕向けられて、どうしようもない状態になってる気もする。
make時の表示の無駄が多すぎて、特に警告が出ていても見逃しやすいし、HDDも膨大に
消費するし、ダウンロードやアップロードにも莫大な時間がかかるし。

なんだか、アメリカと北欧の社会的環境以外ではとっても負担が大きいかも、
488
(1): 396 2018/02/23(金)12:36 ID:rGoiNTvu(6/9) AAS
>>486
意味が分かりません。
489
(1): 2018/02/23(金)12:38 ID:o5jNB0tx(3/6) AAS
>>488
ここにソースコードを書けば5chが権利を主張する恐れがある
あなたが書いたものであっても
それは問題でしょう?
490
(1): 396 2018/02/23(金)12:41 ID:rGoiNTvu(7/9) AAS
MSのやり方に困った人が集まってくるのがLinux。
でも、Linuxのやり方にもまた困る。UbuntuのUpdateも自分には出来ない。
なぜなら、HDDのパーティションの容量が足りないのと、DLに時間がかかりすぎるからと、
クリーンインストールしなきゃならないから、せっかく入れた Wine や Wz, VC++ などの再
インストールに莫大な時間がかかってしまうのとで。それでやっとの思いでなんとか協力
したいと思っているのに、また、ライセンスがどうのこうのとか。

わけが分からない。LinuxやUbuntuのバグに悩まされて、しょっちゅう Logout と Login
を繰り返しながら、やっとの思いでやってます。
491: 2018/02/23(金)12:42 ID:k4GWhlfR(1) AAS
MacでWine使ってるけど似たようんだもんだわ。
492: 2018/02/23(金)12:42 ID:o5jNB0tx(4/6) AAS
OSSやLinuxの問題ではなくて
5chのライセンス扱いの問題
493
(1): 396 2018/02/23(金)12:43 ID:rGoiNTvu(8/9) AAS
>>489
そんな心配はないはずです。

自分は権利を放棄するつもりでやってますし、法的には Wine の LGPL が優先されて、
5ch は権利は主張できないハズ。もし、権利を主張するなら、5ch自体が人が来なくなって、
閉鎖されるでしょう。
494: 2018/02/23(金)12:46 ID:o5jNB0tx(5/6) AAS
>>493
OSSのソースコードを5chに書き写したらライセンスが移るかというとそうではないと思うけど
問題にされる可能性が存在する
新規のソースコードだった場合など、5chが権利を主張してOSSで扱えない可能性が出てくる
495: 2018/02/23(金)12:49 ID:l6yAbvNG(1) AAS
>>490
Linux板でそういうこと言っても住人を不快にさせるだけだよ
誰も頼んでないのに愚痴言われてもさ
ブログか何かに書けば?
496
(1): 2018/02/23(金)12:50 ID:FG6aVYHX(1) AAS
とはいっても、勝手に転載するな、の主張は現在進行でバンバンやってますからねえ…
497: 2018/02/23(金)12:52 ID:o5jNB0tx(6/6) AAS
>>496
他所が権利を主張するコードの利用をOSS側が許すかという問題にかかわってきて
それは5chとは別になるね
498: 396 2018/02/23(金)13:42 ID:rGoiNTvu(9/9) AAS
【ついに出来た】

x11drv_surface_flush() の中で、

update_surface_region( surface );

を実行後、

XPutImage(・・・);
XFlush( gdi_display );
XSync( gdi_display, TRUE );
XSynchronize( gdi_display, True );
省14
499: 2018/02/23(金)17:33 ID:HLL3Qr1p(1) AAS
日本語でパッチの記述を書いてくれれば、英訳してくれる奴がスレにいると思うな。

最悪ぐぐる翻訳でも。

あとは日本人でwineにコミットしてる人を探してパッチを仲介してもらうとか…
500
(1): 2018/02/24(土)00:28 ID:zOhbGEn1(1) AAS
だいぶ前のレスだけれど、 >>439 は信じるなよ。
Wineに修正を送る方法はgit format-patchで整形したパッチを
wine-devel@winehq .orgにメールする方法だからな。(前近代的に感じるかもしれないけれど)
他にも要件がいろいろあるから、 外部リンク:wiki.winehq.org を一読した方がいいと思う。
501: 396 2018/02/24(土)02:46 ID:OWf5FxmD(1/3) AAS
>>500
WINE 本家に正式採用されなくてもいいなら、github にプルリクエストを送る、なんて
事は可能なんでしょうか。

ライセンス上は、修正した箇所のソースの断片でも、どこでもいいからネット上のどこかに
アップロードしておけば良いんだと思うんですが。

ネットの回線が遅いから、自分が全く修正してない部分まで全部アップロードというのは
かなり困ります。
502
(1): 396 2018/02/24(土)02:53 ID:OWf5FxmD(2/3) AAS
要は、著作権が発生するようなソースを書かなければいいんですね。

WINE で、WS_EX_LAYERED の場合に、現状の様に XShape を使わずに、
XCreateWindow の depth に 32 を指定して、ARGB カラーを使うようにして
透明化を実験して見たところ、高速になったようです。

まだ、中途半端ですが。
1-
あと 500 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.043s