UNIXプラットフォームのデフォルト・パイプラインはX11パイプラインです。このパイプラインでは、画面へのレンダリングや、特定タイプのオフスクリーン・イメージ(VolatileImage
など)または「互換性のある」イメージ(GraphicsConfiguration.createCompatibleImage()
メソッドで作成されたイメージ)へのレンダリングを行う際に、Xプロトコルが使用されます。そのようなタイプのイメージは、X11ピックスマップ内に格納すればパフォーマンスを改善できます(特にリモートXサーバーの場合)。
さらに、Java 2Dでは特定の場合に、Xサーバー拡張(MIT X共有メモリー拡張、ダイレクト・グラフィックス・アクセス拡張、BufferStrategy
API使用時のダブル・バッファリング用ダブル・バッファ拡張など)が使用されます。
構成によっては、追加パイプラインのOpenGLパイプラインによってパフォーマンスが向上することもあります。
トラブルシューティングの対象となるX11パイプラインのプロパティは次のとおりです。
Java 2Dではデフォルトで、特定タイプのオフスクリーン・イメージの格納やキャッシングにX11ピックスマップが使用されます。ピックスマップに格納できるイメージのタイプは、次のものだけです。
不透明イメージ(この場合、ColorModel.getTransparency()
からTransparency.OPAQUE
が返される)
1ビット透明イメージ(別名「スプライト」、Transparency.BITMASK
)
イメージの格納にピックスマップを使用するメリットは、ドライバの判断でフレーム・バッファのビデオ・メモリー内に配置できる点にあります(そうした場合、これらのピックスマップを画面や別のピックスマップにコピーする際の速度が改善される)。
ピックスマップを使用すれば、通常はパフォーマンスが向上します。ただし、場合によっては逆になることもあります。そのような場合は通常、Xプロトコルを使って実行できない操作(アンチエイリアス、アルファ合成、単純な移動変換よりも複雑な変換など)が使用されています。
これらの操作については、X11パイプラインは組込みソフトウェア・レンダラを使ってレンダリングを行う必要があります。これにはほとんどの場合、ピックスマップの内容を読み取って(リモートXサーバーの場合はネットワーク経由で)システム・メモリーに格納し、レンダリングを実行したあと、それらのピクセルを元のピックスマップに送信するという操作が含まれます。そのような操作ではパフォーマンスが大幅に低下する可能性があります(特にXサーバーがリモートの場合)。
X11パイプラインの使用を無効にする2つの例を次に示します。
X11パイプラインのピックスマップの無効化:
Java2Dでのピックスマップの使用を無効にするには、Java VMに次のプロパティを渡します。-Dsun.java2d.pmoffscreen=false
。
X11パイプラインの共有メモリー・ピックスマップの無効化:
ピックスマップからのピクセルの読取りを必要とするそのような操作の、全体のパフォーマンスに対する影響を最小限に抑えるため、X11パイプラインは読み取り頻度の高いイメージの格納に共有メモリー・ピックスマップを使用します。注意: 共有メモリー・ピックスマップは、ローカルXサーバーの場合にのみ使用できます。
共有メモリー・ピックスマップを使用するメリットは、X11プロトコルをバイパスしてパイプライン内のピクセルにパイプラインから直接アクセスできる点にあり、その結果、パフォーマンスが向上します。
イメージはデフォルトでは通常のXサーバー・ピックスマップ内に格納されますが、あとでそのようなイメージからの過剰な読取りがパイプラインによって検出された場合には、共有メモリー・ピックスマップにイメージを移動できます。イメージのコピー回数が十分な数に達したら、元のサーバー・ピックスマップにイメージを移動できます。
このパイプラインでは、共有メモリー・ピックスマップの使用を制御する方法が2つ用意されています。それらを無効にする方法と、すべてのイメージが常に共有メモリー・ピックスマップに強制的に格納されるようにする方法です。
共有メモリー・ピックスマップを無効にするには、J2D_PIXMAPS
環境変数をserver
に設定します。これが、リモートXサーバーの場合のデフォルトになります。
すべてのピックスマップが強制的に共有メモリー内に作成されるようにするには、J2D_PIXMAPS
をshared
に設定します。
まず、共有メモリー・ピックスマップを強制してみます。パフォーマンスが向上することがよくあります。ただし、特定のビデオ・ボード/ドライバ構成では、レンダリング・アーティファクトまたはクラッシュを回避するために共有メモリー・ピックスマップを無効にすることが必要な場合があります。
デフォルトでは、Java 2DのX11パイプラインはMIT共有メモリー拡張(MIT SHM)を使用します。この拡張を使えば、クライアント(Javaアプリケーション)とXサーバー間のデータ交換の速度が向上するため、Javaアプリケーションのパフォーマンスが大幅に改善される可能性があります。
次は、Javaアプリケーションのパフォーマンスを向上させる2つの方法です。
XサーバーおよびJava 2Dの共有メモリーの増加:
Oracle Solarisオペレーティング・システム・リリース8以前ではときどき、システム(および特にXサーバー)で使用可能な共有メモリーの量を増やす必要がありましたが、これは、デフォルトが低すぎてレンダリングのパフォーマンスが低下することがあったからです。共有メモリーや共有メモリー・セグメントの量を増やすと、パフォーマンスが向上する可能性があります。
Oracle Solarisオペレーティング・システム上のデフォルト設定を変更するには、例11-1に示すように、/etc/systemファイルを編集してshmsys:shminfo_*
の設定を変更します。注意: これは、Oracle Solaris 9以降では不要です。
例11-1 システム・ファイルの設定
set shmsys:shminfo_shmmax=10000000 set shmsys:shminfo_shmni=200 set shmsys:shminfo_shminfo=150
Linuxでこの設定を構成するには、/proc/sys/kernel/shm*ファイルを編集します。
X11パイプラインの共有メモリー拡張の無効化:
古いXサーバーや共有メモリー拡張で問題(クラッシュやレンダリング・アーティファクトなど)が発生する場合、拡張を無効にできると便利です。MIT SHMの使用を無効にするには、J2D_USE_MITSHM
環境変数をfalse
に設定します。
SPARCハードウェアでは、フレーム・バッファがSunのDGA (ダイレクト・グラフィックス・アクセス) Xサーバー拡張をサポートしていて、フレーム・バッファにアクセスするための対応するモジュールがJava 2Dに含まれている場合、画面へのレンダリングにDGAが使用されます。
オフスクリーン・イメージはすべてJavaヒープ・メモリー内に存在しており、それらへのレンダリングにはJava 2Dのソフトウェア専用レンダリング・パイプラインが使用されます。これは、オフスクリーン・イメージにX11ピックスマップが使用される通常のUNIX構成とは異なっています。
次のユースケースは、DGA拡張サポートを検出し、DGAを無効/有効にする方法を説明します。
レンダリングのためのDGA拡張:
画面へのレンダリング時にDGA拡張が使用されているかどうかを検出するには、なんらかのレンダリングを行うかGUIを表示する任意のJavaアプリケーションを実行し、そのアプリケーション起動時に/tmp/wg*ファイルが作成されたかチェックします。アプリケーションを終了し、ファイルが削除されたことを確認します。その場合、このシステムではJava 2DがDGAを使用しています。
一般的なDGAの問題:
DGAではフレーム・バッファのビデオ・メモリーに直接アクセスできるため、典型的な問題として、ウィンドウ境界の外側の破損、完全なシステム、Xサーバー・ロックアップなどが挙げられます。
DGAの有効化または無効化:
DGAが使用されていることが確認できた場合、最初に試すべきことは、その無効化です。これを行うには、NO_J2D_DGA
環境変数をtrue
に設定します。するとデフォルトのUNIXパスで強制的に、画面へのレンダリングにX11のみが使用され、オフスクリーン・イメージの高速化にピックスマップが使用されるようになります。
ときには、画面へのレンダリングにDGAを使用し、ピックスマップの使用を有効にすることが有益な場合もあります。オフスクリーン・イメージの高速化のためにピックスマップの使用を強制するには、アプリケーションの起動時に-Dsun.java2d.pmoffscreen=true
プロパティを設定します。
SPARCプラットフォームの特定のビデオ・ボードでは、複数のビジュアルがXサーバーから使用できます。Java 2Dはデフォルトで最適なビジュアルを選択しようとしますが、この「最適」というのは通常、ビットの深さがより深いビジュアルを指します。たとえば一部のOracle Solarisオペレーティング・システム・リリースでは、デフォルトX11ビジュアルは8ビット疑似カラーですが、24ビットのビジュアルも使用できます。そのような場合、Java 2Dは、Javaウィンドウのデフォルトとして24ビット・トゥルーカラー・ビジュアルを選択します。
別のビジュアルに対応するGraphicsConfiguration
オブジェクトでJavaトップレベル・ウィンドウを作成することも可能ですが、場合によっては、代わりに別のデフォルト・ビジュアルをJavaに使用させる必要が生じることがあります。これを行うには、FORCEDEFVIS
環境変数を設定します。これは、true
に設定してデフォルトXサーバー・ビジュアルの使用を(たとえ最適でなくても)強制することができる一方で、xdpyinfo
などのツールで報告されたビジュアルIDに対応する16進数に設定することもできます。
Xサーバーのデフォルト・ビジュアルを確認するには、xdpyinfo
コマンドを実行し、default visual id
のフィールドを確認します。