Edited at

Inside Wine; 透明色

More than 1 year has passed since last update.

目次


Inside Wine; 透明色


親が Desktop Window の場合の Win32 の Window は、X Windowで は、depth = 24 で、XCreateWindow() されます。これは、8*3 = 24 BIT の、RGB カラーに相当します。

dwExStyle に WS_EX_LAYERED 属性を指定して、かつ、完全透明色を用いている場合は、X Window 側の depth は、24 のままです。透明は、XShpae を用いて、実装されています。XShape は、本来は、長方形以外の輪郭を持つ Window を作成するためのものです。だから、実測では、一回辺り、完全に処理が終わるまで、0.15秒(150 ms)程度の比較的長い時間がかかります。それは、XShape の設計においては、Window の外形は、Window 作成時に一回だけ設定されることを前提にしているためでしょう。問題なのは、その速度が遅いことよりも、Linux の場合、XFlush()、XSync() を行っても、10 ms 程度ですぐに帰ってきてしまい、本当の処理が完了する 150 ms は、WINE や、アプリが感知する方法が見つからない事です。

このことは、再描画が必要な時には、いったん、InvalidateRect()で、(再描画が必要な事を示す)マークだけしておけば、メッセージ・キューに残されている未処理のメッセージ(比較的、マウスやキーボードのメッセージであることが多い)の個数によって直前または最近の描画の重たさを測ることで、今後の WM_PAINT の発行タイミングを自動調整する方針を取っている Win32 では、致命的な問題へと発展し、Linux OS の数分間以上の事実上のハングアップ(操作不能状態)に至ります。そうなった場合、マウスカーソルだけしか動かせなくなり、タスクバーも全く機能しなくなります。そのことは、後に述べる予定です。大筋で言えば、処理が追いついて無いのに大量の Request を X Server にとめどもなく発行してしまうために、待ち行列に未処理のリクエストが大量に溜まってしまった X Server を「救うため」、Linux システムが X Server のみに CPU リソースを与え、他の プロセスは、完全停止状態にしてしまうことが原因と考えられます。


X Window で、XShape を使わない本当の透明色

X Window で透明色を扱うのはとても簡単です。

XCreateWindow() を、depth = 32 として Window を作成するだけです。

これで、色値が、ARGB の A,R,G,B 構成となり、A が専門用語で「α値」と呼ばれる値になります。

A = 0 で完全透明、A = 255 で完全不透明となり、その間の値では、中間的な半透明となります。基本的には、最終的な色値 D2 は、その背面にある色値 D に対して、

D2 = (int)( ( D * (255.0 - A) + S * A ) / 255.0 );

のような計算式で計算されます。S は、上に重なっている所の物の色(ARGB の RGB 部分)です。


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


aaa

あああ


end