12 Java 2Dパイプラインのレンダリングおよびプロパティ

この章では、パイプラインのレンダリングおよびプロパティを変更する場合にJava 2D APIで発生する可能性がある、いくつかの最も一般的な問題のトラブルシューティングのための情報およびガイダンスを提供します。

Java 2Dプロパティのサマリーについては、「Java 2Dのプロパティ」を参照してください。

別のパイプラインを選択したりパイプラインのプロパティを操作したりすれば、問題の原因を特定できたり、しばしば回避方法を発見できたりする可能性があります。

通常、構成で使用されるデフォルトのパイプラインを確認することで、Java 2Dパイプラインの問題のトラブルシューティングを行うことができます。次に、パイプラインを別のものに変更するか、デフォルト・パイプラインのプロパティを変更します。

問題が解消すれば、回避方法が見つかったことになります。問題が継続する場合は、別のプロパティを変更するか別のパイプラインに変更してみます。

Java 2Dでは一連のパイプラインが使用されますが、これは大まかに、プリミティブをレンダリングするためのさまざまな方法として定義できます。これらのパイプラインは次のとおりです。

Linux: X11パイプライン

Linuxオペレーティング・システムでは、デフォルト・パイプラインはX11パイプラインです。このパイプラインでは、画面へのレンダリングや、特定タイプのオフスクリーン・イメージ(VolatileImagesなど)または「互換性のある」イメージ(GraphicsConfiguration.createCompatibleImage()メソッドで作成されたイメージ)へのレンダリングを行う際に、Xプロトコルが使用されます。

これらのタイプのイメージは、X11ピックスマップ内に格納すればパフォーマンスを改善できます(特にリモートXサーバーの場合)。

さらに、Java 2Dでは特定の場合に、Xサーバー拡張(MIT X共有メモリー拡張、ダイレクト・グラフィックス・アクセス拡張、BufferStrategy API使用時のダブル・バッファリング用ダブル・バッファ拡張など)が使用されます。

構成によっては、追加パイプラインのOpenGLパイプラインによってパフォーマンスが向上することもあります。

トラブルシューティングの対象となるX11パイプラインのプロパティは次のとおりです。

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_PIXMAPSsharedに設定します。

X11パイプラインのMIT共有メモリー拡張

Java 2DのX11パイプラインはMIT共有メモリー拡張(MIT SHM)を使用しますが、この場合、クライアントとXサーバーの間のデータの交換が速くなります。この機能により、Javaアプリケーションのパフォーマンスが大幅に向上する場合があります。

次は、Javaアプリケーションのパフォーマンスを向上させる2つの方法です。

  • XサーバーおよびJava 2Dの共有メモリーの増加:

    ときにはシステム(および特にXサーバー)で使用可能な共有メモリーの量を増やすことが必要な場合がありますが、これは、デフォルトが低すぎてレンダリングのパフォーマンスが低下することがあるからです。共有メモリーや共有メモリー・セグメントの量を増やすと、パフォーマンスが向上する可能性があります。

    Linuxでこの設定を構成するには、/proc/sys/kernel/shm*ファイルを編集します。

  • X11パイプラインの共有メモリー拡張の無効化:

    古いXサーバーや共有メモリー拡張で問題(クラッシュやレンダリング・アーティファクトなど)が発生する場合、拡張を無効にできると便利です。MIT SHMの使用を無効にするには、J2D_USE_MITSHM環境変数をfalseに設定します。

Windows OS: DirectDraw/GDIパイプライン

Windowsプラットフォームのデフォルト・パイプラインは、DirectDrawパイプラインとGDIパイプラインを組み合わせたものであり、DirectDrawパイプラインで実行される操作もあれば、GDIパイプラインで実行される操作もあります。高速化されたオフスクリーンやオンスクリーン表面へのレンダリングには、DirectDrawとGDIのAPIが使用されます。

Direct3Dパイプラインの問題としては、レンダリング・アーティファクト、クラッシュ、パフォーマンス関連の問題などが考えられます。

構成によっては、追加パイプラインのOpenGLパイプラインによってパフォーマンスが向上することもあります。

次は、レンダリング・アーティファクト、クラッシュ、パフォーマンス関連の問題など、Direct3Dパイプラインの問題のトラブルシューティングを行う3つの例です。

  • DirectDrawパイプラインの無効化:

    DirectDrawが無効になっていると、すべての操作がGDIで行われます。DirectDrawの使用を無効にするには、-Dsun.java2d.noddraw=trueフラグを指定します。この場合、すべてのオフスクリーン・イメージがJavaヒープ内で作成され、それらへのレンダリングにはデフォルトのソフトウェア・パイプラインが使用されます。画面へのオフスクリーン・イメージのコピーだけでなく、オンスクリーンのすべてのレンダリングにもGDIが使用されます。

  • DirectDrawパイプラインの有効化:

    なんらかの理由でパイプラインがデフォルトで無効化された場合にそれを有効にするには、-Dsun.java2d.noddraw=falseフラグをVMに指定します。

    ただし通常は、そもそも無効にされた理由が存在するので、強制しないほうが得策です。

  • 組込みパント・メカニズムの無効化:

    一般に、DirectDrawパイプラインはオフスクリーン表面をフレーム・バッファのビデオ・メモリー内に配置しようとしますが、これにより、それらの表面を画面や他の高速化された表面にコピーする操作が高速化される以外に、特定のグラフィックス操作のハードウェア高速化レンダリングも可能となります。

    VRAMベースの表面への非高速化レンダリングの影響を抑えるために、パント・メカニズムが存在します。このメカニズムでは、頻繁に読み取られると判明した表面をシステム・メモリーに移動します。頻繁にコピーされると判明した表面は、ビデオ・メモリーに戻すよう促されることがあります。

    ただし、パイプラインがDirectDraw APIを使用して実行できない操作(アルファ合成、変換、アンチエイリアスなどを使用する操作)については、ソフトウェア・パイプラインを使用してレンダリングが実行されます。これは場合によっては、VRAM内に存在する宛先表面のピクセルを読み取ってシステム・メモリーに格納する必要があることを意味しますが、それは非常にコストの高い操作です。

    特定のビデオ・ボード/ドライバの組合せでは、システム・メモリー・ベースのDirectDraw表面がレンダリング・アーティファクトやその他の問題の原因となることが知られています。DirectDrawパイプラインには、システム・メモリー表面が使用されないようにパント・メカニズムを無効にするための方法が用意されています。

    組込み表面パント・メカニズムを無効にするには、Java VMに-Dsun.java2d.ddforcevram=trueフラグを指定します。

    ノート:

    このメカニズムにより、パフォーマンスが低下することがあります。操作のたびにソフトウェア・ループによってVRAMからピクセルが読み取られる可能性があるためです。この場合は、DirectDrawパイプラインの無効化を検討します。

  • DirectDraw BILT操作の無効化:

    Bit Block Transfer (BILT)操作では、2つのビットマップ・パターンが合成されます。この操作は、Graphics.drawImage() APIの呼出しに対応します。

    場合によっては、DirectDraw BLIT操作を無効にすることでレンダリングの問題を回避できます。かわりにGDI BLITが使用されます。

    ノート:

    この操作によってパフォーマンスが低下する場合があります。代わりにDirectDrawパイプラインの無効化を検討してください。

    DirectDraw BLIT操作の使用を無効にするには、パラメータ-Dsun.java2d.ddblit=falseをJava VMに渡します。

Windows OS: 全画面モードでのDirect3Dパイプライン

フル・スクリーン・モードではこのパイプラインがデフォルトで有効にされます(ドライバが、必要な機能とそのレンダリング品質レベルをサポートしている場合)。

次の項で説明するように、Direct3Dパイプラインを有効にし、その使用を強制できます。

アルファ合成、アンチエイリアス、変換などのレンダリング操作を大量に使用するアプリケーションでは、Direct3Dパイプラインを有効にすることを検討してください。

ただし、このパイプラインをアプリケーションで有効にすることを決定する際には注意してください。たとえば、一部の組み込みビデオ・チップセット(大部分のノートブックで使用されているもの)は、たとえJava 2Dパイプラインの品質要件を満たしていても、Direct3D使用時には良好なパフォーマンスを示しません。

Direct3D APIの問題のトラブルシューティングを行う3つの例を次に示します。

  1. Direct3Dパイプラインの無効化:

    一部の古いビデオ・ボード/ドライバの組み合わせでは、Direct3Dパイプラインで問題(レンダリングとパフォーマンスの両方)が発生することが知られています。これらの場合にパイプラインを無効にするには、パラメータ-Dsun.java2d.d3d=falseをJava VMに渡すか、J2D_D3D環境変数をfalseに設定します。

  2. Direct3Dパイプラインの有効化:
    ウィンドウ・モードとフル・スクリーン・モードの両方でDirect3Dパイプラインを有効にするには、パラメータ-Dsun.java2d.d3d=trueを使用するか、J2D_D3D環境変数をtrueに設定します。

    ノート:

    パイプラインは、ドライバが最小限必要な機能をサポートしている場合にのみ有効になります。
  3. Direct3Dパイプラインのレンダリング問題の診断:

    様々なDirect3Dラスタライザを強制することで、いくつかのレンダリングの問題(ピクセルの欠落や不明瞭なレンダリングなど)を診断できます。J2D_D3D_RASTERIZER環境変数をrefrgbhal、またはtnlのいずれかに設定します。

    これらのラスタライザの詳細は、Direct3Dのドキュメントを参照してください。デフォルトでは、通知された機能に基づいて最適なラスタライザが選択されます。具体的には、refラスタライザでは、Microsoft製のリファレンスDirect3Dラスタライザの使用が強制されます。このラスタライザでレンダリングの問題が再現できない場合、その問題はビデオ・ドライバのバグの可能性が高いと考えられます。

    rgbラスタライザが使用可能なのは、Direct3D SDKがインストールされている場合だけです。Microsoft DirectX 9.0 Software Development Kit (SDK)のソフトウェア・ラスタライザは、Microsoft Direct 3Dと互換性があります。これは、Microsoft DirectX 9.0 Software Development Kit (SDK)用のソフトウェア・ラスタライザに関するサイトから入手できます。または、Microsoft DirectX® End-User Runtimeをダウンロードします。Direct3D SDKの詳細は、Direct3Dバージョン11 DDIのサポートの有効化に関するサイトを参照してください。

    Direct3Dパイプラインのテキスト・レンダリングでパフォーマンスや品質の問題が発生する場合、Direct3Dパイプラインのグリフ・キャッシュで、デフォルトのアルファ・テクスチャのかわりにARGBテクスチャを使用することを強制できます。これを行うには、J2D_D3D_NOALPHATEXTURE環境変数をtrueに設定します。

LinuxおよびWindowsでのOpenGLパイプライン

OpenGLパイプラインは、LinuxおよびWindowsで使用できます。

この代替パイプラインでは、VolatileImagesBufferStrategy APIで作成されたバック・バッファ、および画面へのレンダリング時に、ハードウェア高速化されたクロス・プラットフォームのOpenGL APIが使用されます。

このパイプラインはデフォルト(X11またはGDI/DirectDraw)のパイプラインに比べ、特定のアプリケーションでパフォーマンス上の大きな利点を提供できます。アルファ合成、アンチエイリアス、変換などのレンダリング操作を大量に使用するアプリケーションでは、このパイプラインを有効にすることを検討してください。

OpenGLパイプラインの問題のトラブルシューティングを行うユースケースを次に示します

OpenGLパイプラインの有効化

OpenGLパイプラインはデフォルトで無効になっています。

OpenGLパイプラインの有効化を試みるには、次のオプションをJVMに指定します。

-Dsun.java2d.opengl=True

OpenGLパイプラインが特定のスクリーンに対して正常に初期化されたかどうかに関する、詳細なコンソール出力を受け取るには、オプションをTrueに設定します(大文字「T」に注意)。

最小要件

ハードウェアまたはドライバが最小要件を満たしていなければ、OpenGLパイプラインは有効にされません。

次の要件のいずれかが満たされない場合、Java 2Dはフォール・バックしてデフォルト・パイプライン(LinuxのX11またはWindowsのGDI/DirectDraw)を使用するため、アプリケーションは正しく動作し続けますが、OpenGLの高速化は失われます。

Linuxオペレーティング・システムの最低要件を次に示します。

  • ハードウェア高速化のOpenGL/GLXライブラリがインストールされ、適切に構成されている

  • OpenGLのバージョンが1.2以降

  • GLXのバージョンが1.3以降

  • 使用可能な深度バッファ付きの、少なくとも1つのトゥルーカラー・ビジュアル

Windows OSの最小要件は、次のとおりです。

  • 拡張WGL_ARB_pbufferWGL_ARB_render_texture、およびWGL_ARB_pixel_formatをサポートするハードウェア高速化ドライバ

  • OpenGLのバージョンが1.2以降

  • 使用可能な深度バッファ付きの、少なくとも1つのピクセル形式

起動の問題の診断

OpenGLベースのJava 2Dパイプラインの起動手順に関する詳細情報を取得するには、J2D_TRACE_LEVEL環境変数を使用します。

前述したように、特定のマシン上で様々な理由でOpenGLパイプラインが有効にされない場合があります。たとえば、ドライバが正しくインストールされていない可能性や、報告されたバージョン番号が不十分である可能性があります。あるいは、マシンに搭載されている古いグラフィックス・カードがOpenGLの適切なバージョンや拡張をサポートしていない可能性もあります。

次の例に示すように、J2D_TRACE_LEVEL環境変数を使用してOpenGLベースのJava 2Dパイプラインの起動手順に関する詳細情報を取得できます。

Windowsでは、J2D_TRACE_LEVEL環境変数を設定します。

# set J2D_TRACE_LEVEL=4
# java -Dsun.java2d.opengl=True YourApp

Linuxでは、J2D_TRACE_LEVEL環境変数を設定します。

# export J2D_TRACE_LEVEL=4
# java -Dsun.java2d.opengl=True YourApp

その出力は、プラットフォームや取り付けられたグラフィックス・ハードウェアに応じて異なりますが、OpenGLパイプラインがユーザーの構成で正常に有効にされない理由に関する何らかの洞察を提供してくれます。

ノート:

この出力は特に、Java 2Dチーム宛のバグ・レポートを記入する際に特に役立ちます。

レンダリングおよびパフォーマンスの問題の診断

OpenGLパイプラインはベースとなるグラフィックス・ハードウェアやドライバに非常に強く依存しているため、レンダリングやパフォーマンスの問題の原因がJava 2D、OpenGLドライバのどちらなのかを判定しかねる場合があります。

GL_EXT_framebuffer_object拡張は、VolatileImagesの使用時にレンダリング・パフォーマンスの改善とVRAM消費量の低減を実現します。この「FBO」コード・パスは、OpenGLパイプラインが有効なときにデフォルトで有効になりますが、それは、グラフィックス・ハードウェアとドライバがこのOpenGL拡張をサポートしている場合に限られます。この拡張は一般に、Nvidia GeForce/Quadro FXシリーズ以降およびATI Radeon 9500以降で使用できます。「FBO」コード・パスがアプリケーションの問題の原因となっている疑いがある場合、次のシステム・プロパティを設定してそれを無効にできます:

-Dsun.java2d.opengl.fbobject=false

このプロパティが設定されると、Java 2Dは古いpbuffer-based コード・パスにフォール・バックします。

特定のJava 2D操作で得られる視覚的な結果が、OpenGLパイプラインを有効にしたときとしなかったときで異なる場合、それはおそらく、グラフィックス・ドライバのバグを示しています。同様に、OpenGLパイプラインを有効にしたときに、しなかった場合よりもJava 2Dレンダリングのパフォーマンスが大幅に悪化する場合、その原因はおそらくドライバまたはハードウェアの問題です。

どちらの場合も、通常のバグ報告チャネルを通じて詳細なバグ・レポートを提出してください。「バグ・レポートの提出」を参照してください。バグ・レポートの提出時にはできるだけ詳しく記述し、次の情報を含めてください。

  • オペレーティング・システム(Ubuntu Linux 6.06、Windows XP SP2など)
  • グラフィックス・ハードウェアの製造元とデバイスの名前(Nvidia GeForce 2 MX 440など)
  • ドライバの正確なバージョン(ATI Catalyst 6.8、Nvidia 91.33など)
  • J2D_TRACE_LEVEL=4をコマンド行に指定したときの出力(前の項で説明)
  • Linuxを使用している場合は、glxinfoコマンドの出力

最新のOpenGLドライバ

OpenGLパイプラインはOpenGL APIおよびベースとなるグラフィックス・ハードウェアやドライバに強く依存しているため、最新のグラフィックス・ドライバがマシンにインストールされているのを確認することが非常に重要です。ドライバは、グラフィックス・カードの製造元のWebサイトからダウンロードできます(次の表を参照)。

製造元 プラットフォーム 動作確認済みのカード

AMD/ATI

Linux、Windows

Radeon 8500以降、FireGLシリーズ

Nvidia

Linux、Windows

GeForce 2シリーズ以降、Quadro FXシリーズ以降

Xi Graphics

Linux

各種(Xi Graphicsで確認)