2017年7月30日日曜日

どうしてLinuxではforkしたままだと共有ライブラリを読まないんだろう...。

forkしてexecするためのクラスを作ったのだが、ここで親プロセスではなく子プロセスが戻ってきてしまうように間違ったところ、共有ライブラリを読んでくれなくて死亡。

これはforkしてexecしてしまう場合には問題にならないが、プリエンプティブなスレッドが欲しい場合に問題になる。以前これについて調査したところ「forkする前になんか呼び出して予めライブラリを読ませとけ」というのが回答だったし他の回答はなかったのでこれがベストなんだろう。

メモリ空間をまるごと共有みたいな真似せずに必要ならmmapして共有しとけということかも知れぬ。

2017年7月28日金曜日

キャプチャのためのGLXコンテキスト

描画先が根窓ではない以上、キャプチャのためのGLXコンテキストが必要になる...というわけで作りかけだった部分を一通りちゃんと組んで安定してGLXコンテキストを扱えるようにしてみた...相変わらず値窓は真っ黒なわけだけどこれは後でXephyrの窓になるように修正するのでおk。

GLXコンテキストは何かマズイことをするとエラーを出すとかじゃなくてsegfaultで落ちるというセンシティブなブツなのだが、ラッパクラスがちゃんと動くことを確認できたのでこれで気軽に子コンテキストを扱えるようになるというもの。キャプチャに関してはあとはXephyrの起動と本命窓の特定ってところで、イベントの配信が巧く行けばアプリケーション側はVRHMDを外さずに開発できるようになる。

VRHMDの脱着は結構厄介な問題で、うちではDK1のスポンジはボロボロで、DK2のスポンジは切れた...と思ったら剥がれてただけなので補修しとこう。ともかくVRな開発で脱着を繰り返すとすごい勢いで痛むのだ。VRカバーってのもあるけど取れやすくて困るし...単純に面倒というのも小さくはないけどね。

2017年7月27日木曜日

WindowManagerの作り方

wOCEの前身であるRWMはWMとして書かれたが途中でWMではなくディスプレイマネージャであることに気付いて方針転換した関係上、おそらくwOCEではもう使わない情報だろうが本当に探すのが大変なのでWMの作り方へのリンクをメモしておく。

現在本当に探しているのは「窓を最小化するときには何をすべきなのか」なのだが、またこの情報がない。すぐに出てくるXIconifyWindowはWMに対してアイコン化するというメッセージを送るだけなので実際の処理はWMがする。WMの好きにやっていいってことなんだろうけど。

そんなもんが必要なのはXephyrの窓を表示しておいても邪魔なだけというのが理由。どのみちwODMの画面が上になるのだが無意味に表示させてオーバーラップの処理しても仕方がないので。

だがXの処理では表示させない窓はUnmapすることになってて、しかしUnmapすると中身が一切合切なくなってしまうので使えないし、窓がIconizeされるときにはUnmapされない。なので窓がIconizeされる時に何してるのか調べる必要があるというわけ。


「アイコナイズした時の座標」みたいなXリソースがあったのでおそらくこれを使うのだろう。値が非常に大きいので要は最小化した時は画面外に移動しているようだ...結局これかぁ...。

特定プロセスが作った窓を探す

X画面を直接キャプチャしようとするといろいろ問題があるので、X画面キャプチャのためにはXephyrやXnestを起動してその窓を探す必要がある。PIDはwODMからそれらを起動する時に得られるとしても、特定PIDの窓を探す方法がわからなかったので調査した。

StackOverflowの「How to get an X11 Window from a Process ID?」にあった。同様のエントリはもうひとつ。他の似たようなエントリはシェルスクリプトを使うものだったのでこの件とは無関係だ。

それによるとどうやら「_NET_WM_PID」ってラベルでAtomとして書き込まれているらしい。X11には窓に任意のデータを追加する機能があるのでXLibあたりがそれを使って書いといてくれているようだ。

--

間違い。_NET_WM_PIDとかの値はアプリケーションが自分で設定する必要がある。おそらく各種フレームワークはやってくれるだろうけど。

2017年7月26日水曜日

イベントがおかしい

SightEnterイベントが連続して送られてくるのだが...調べてみると一番近いWidgetを探すメソッドが奥のWidgetに反応しちゃってて、奥をWidgetが通る度にLeave/Enterが発生しているという困った状況になってる。

...んだが原因判明。ある点に対応するWidgetを探すときに子要素を辿る方法が間違っていたのが原因。間違っていたというより完全に余計なことをしているので、他の何かと間違って入れたものと思われるorz

ともかくこれで長かった「サンプルアプリケーションを作る(1)」をclose。

2017年7月23日日曜日

VSYNCを待たない問題(描画処理を待たせてみた)

フレーム時間の70%を経過してから描画処理が開始されるように設定してみたところ、目論見通り他の処理を高速化できた。最初の状態の10秒以上が0.5秒になると言ったところ。ほぼVSYNCを待つ環境と同様なのでこの方向で間違いはないだろう。

あとは描画負荷に合わせて待ち時間を調整したりフレームバッファの初期化なんかを待ち時間の前に入れて並列性を高めてみたりでこのあたりは完成とする。VSYNCに同期できないのは腹立たしいが現状では難しいので後回しにしとく。

VSYNC問題は続く

glSwapBufferがVSYNCを待たない問題はまだ解決していない。これを解決しないと何してもクッソ遅いので避けて進むわけにはいかないし。VSYNCを待つような設定や処理にしても待つのは処理がVSYNCを跨ぐ場合だけで、そうでない時は何も待たないのでほとんど意味がない。これはAMDのドライバだけでなくIntelのドライバも同様だ。

描画スレッドを待たせるだけなら周期的に描画スレッドを寝かせればいい。VRでは描画タイミングが大事なのでVSYNCからの時間情報が欲しいところだがないなら仕方ないというところで、ひとまず周期の最初の半分以上は描画スレッドを寝かすことにする。pthreadはコオペレイティブなので他のスレッドが長引くと大きく時間が狂うわけだが...。


Bloggerが吐くHTMLがアホなので直接HTMLで書くことにした。改行なんて吐いてんなよ。しかも微妙に間違ってるし。

2017年7月7日金曜日

Xのキャプチャを「表側」から...という計画

画面側のX環境をキャプチャしてVRHMDを脱がずに開発したいところだが、デスクトップ環境がルート窓を使ってなかったりしててなかなかうまく行かない。そこでXephyrとかXvfbとかXnestとかみたいな仮想画面を使ってルート窓からではなく「表側」からのキャプチャを試してみようと思う。

実のところルート窓をキャプチャするのは実画面のサイズに縛られたり、wODMの出力までキャプチャされちゃったり、Xdamageでキャプチャすると遅かったりでイマイチなわけだけど、仮想画面なら実画面を無視してサイズを設定できるしXephyrなら動画も楽々だし。

実装するにはXephyrの窓を探さなければならないわけだが。

2017年7月3日月曜日

VSYNC問題

グラボのドライバの中にはVSYNC待ちを無視してくれるものがあって、そういうドライバに当たると描画が忙しくてメッセージの転送や処理が回らなくなることがある。また逆に画像転送などのようにメッセージ処理に時間を取られて描画が疎かになったりする。なので描画とメッセージ処理を別のスレッドにした。スレッドの管理にはpthreadを使う。

メッセージ処理といってもテクスチャのアップデートなどがあるので描画スレッドとOpenGLのリソースは共有しなければならない。X環境ではこれはglXCreateContextでGLXコンテキストを作るときに元のGLXコンテキストを指定してやることでできる。なお、子コンテキストは親スレッドで作る

で、子コンテキストを作ったらスレッドを起こす。スレッドで子コンテキストをglxMakeCurrentすればおしまい。glxMakeCurrentを調べればわかるがpthreadのスレッドはGLXコンテキストを切り替え対象にしててちゃんと切り替えてくれる。余計な心配は要らない。

引っ越すことにした。

引っ越し先。 見えるかな。