web-dev-qa-db-ja.com

Javaハードウェアアクセラレーション

私はJavaのハードウェアアクセラレーション機能を調査することに時間を費やしてきましたが、オンラインで直接見つけたサイトがなく、質問のいくつかに明確に答えていなかったため、まだ少し混乱しています。それで、Javaでのハードウェアアクセラレーションについて私が持っている質問は次のとおりです。

1)Eclipseバージョン3.6.0では、最新のJava Mac OS X(1.6u10だと思います)のアップデート)で、ハードウェアアクセラレーションはデフォルトで有効になっていますか?

someCanvas.getGraphicsConfiguration().getBufferCapabilities().isPageFlipping()

ハードウェアアクセラレーションが有効になっているかどうかを示すことになっています。メインのCanvasインスタンスでそれを実行すると、プログラムはtrueを報告します。ハードウェアアクセラレーションが現在有効になっていない場合、またはデフォルトで有効になっていない場合、有効にするにはどうすればよいですか?

2)BufferedImageとVolatileImageの違いについて、主にVolatileImageはハードウェアアクセラレーションされたイメージであり、高速コピー元操作のためにVRAMに保存されるという記事を、あちこちで見ました。ただし、BufferedImageがハードウェアアクセラレーションであると言われる場合もあります。 BufferedImageハードウェアは私の環境でも高速化されていますか?両方のタイプがハードウェアアクセラレーションされている場合、VolatileImageを使用する利点は何ですか?両方にアクセラレーションがある場合にVolatileImageを使用する利点についての私の主な仮定は、VolatileImageがVRAMがダンプされたことを検出できるということです。しかし、BufferedImageがアクセラレーションもサポートするようになった場合、メモリがダンプされた場合に備えて、同じ種類の検出が組み込まれ、ユーザーから隠されているだけではないでしょうか。

3)使用する利点はありますか

someGraphicsConfiguration.getCompatibleImage/getCompatibleVolatileImage()

とは対照的に

ImageIO.read()

チュートリアルでは、レンダリングウィンドウを適切に設定するためのいくつかの一般的な概念を読んでいます( チュートリアル )。getCompatibleImageメソッドを使用します。これはBufferedImageを返すと信じており、「ハードウェアアクセラレーション」画像を取得します。高速描画。ハードウェアアクセラレーションであるかどうかについての質問2に関連しています。

4)これはハードウェアアクセラレーションが少ないですが、私が興味を持っていたものです。どのグラフィックを描画するかを注文する必要がありますか? C/C++経由でOpenGLを使用する場合、現在のテクスチャを切り替える必要がある回数を減らすために、一度に描画する必要があるすべての場所に同じグラフィックを描画することが最善であることを知っています。私が読んだことから、Javaが私のためにこれを処理し、物事が最適な方法で描画されることを確認するように見えますが、繰り返しますが、このようなことを明確に言ったことはありません。

5)どのAWT/Swingクラスがハードウェアアクセラレーションをサポートし、どのクラスを使用する必要がありますか?現在、JFrameを拡張するクラスを使用してウィンドウを作成し、そこにCanvasを追加してBufferStrategyを作成しています。これは良い習慣ですか、それとも私がこれを実装する必要がある他のタイプの方法がありますか?

お時間をいただき、誠にありがとうございました。いくつかの質問にお答えできるよう、明確な質問と十分な情報を提供できれば幸いです。

19
Freezerburn

1)これまでのところ、ハードウェアアクセラレーションはデフォルトで有効になることはなく、私の知る限り、まだ変更されていません。レンダリングアクセラレーションをアクティブにするには、この引数(-Dsun.Java2d.opengl = true)をプログラムの起動時にJavaランチャーに渡すか、レンダリングライブラリを使用する前に設定します。System.setProperty("Sun.Java2d.opengl", "true");これはオプションのパラメータです。

2)はいBufferedImageは、揮発性メモリの管理の詳細の一部をカプセル化します。これは、BufferdImageが高速化されると、そのコピーがVolatileImageとしてV-Ramに保存されるためです。

BufferedImageの利点は、含まれているピクセルをいじらない限り、graphics.drawImage()の呼び出しのようにコピーするだけで、BufferedImageが高速化されます。特定の指定されていないコピー数の後、それはあなたのためにVolatileImageを管理します。

BufferedImageの欠点は、画像編集を行っている場合、BufferedImageのピクセルを変更することです。場合によっては、加速しようとするのを諦めます。その時点で、探している場合は編集のためのパフォーマンスの高いレンダリングでは、独自のVolatileImageの管理を検討する必要があります。 BufferedImageがレンダリングを高速化することを諦める操作がどれかわかりません。

3)createCompatibleImage()/createCompatibleVolatileImage()を使用する利点は、ImageIO.read()がデフォルトでサポートされている画像データモデルへの変換を行わないことです。したがって、PNGをインポートすると、PNGリーダーによって作成された形式で表示されます。これは、GraphicsDeviceによってレンダリングされるたびに、最初に互換性のある画像データモデルに変換する必要があることを意味します。

BufferedImage image = ImageIO.read ( url );
BufferedImage convertedImage = null;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment ();
GraphicsDevice Gd = ge.getDefaultScreenDevice ();
GraphicsConfiguration gc = Gd.getDefaultConfiguration ();
convertedImage = gc.createCompatibleImage (image.getWidth (), 
                                           image.getHeight (), 
                                           image.getTransparency () );
Graphics2D g2d = convertedImage.createGraphics ();
g2d.drawImage ( image, 0, 0, image.getWidth (), image.getHeight (), null );
g2d.dispose()

上記のプロセスでは、image io apiで読み込まれた画像が、デフォルトの画面デバイスと互換性のある画像データモデルを持つBufferedImageに変換されるため、レンダリング時に変換を行う必要はありません。これが最も有利なのは、画像を非常に頻繁にレンダリングする場合です。

4)ほとんどの場合、Javaがこれを実行しようとするため、画像レンダリングをバッチ処理する努力をする必要はありません。これを実行できない理由はありませんが、一般に、このようなパフォーマンスの最適化を実行する前に、アプリケーションのプロファイルを作成し、画像レンダリングコードにボトルネックがあることを確認することをお勧めします。主な欠点は、JVMごとに実装方法が少し異なることです。拡張機能は無価値かもしれません。

5)私の知る限り、あなたが概説した設計は、ダブルバッファリングを手動で実行し、アプリケーションをアクティブにレンダリングする場合の優れた戦略の1つです。 http://docs.Oracle.com/javase/7/docs/api/Java/awt/image/BufferStrategy.html このリンクには、BufferStrategyの説明があります。 。説明では、BufferStrategyオブジェクトを使用してアクティブレンダリングを行うための推奨される方法であるコードスニペットを示しています。この特定の手法をアクティブなレンダリングコードに使用します。唯一の大きな違いは、私のコードにあることです。あなたのように、私はBufferStrategyに置いたCanvasのインスタンスにJFrameを作成しました。

16
Zixradoom

いくつかの 古いドキュメント から判断すると、_Sun.Java2d.opengl_プロパティをチェックすることで、ハードウェアアクセラレーションがオンになっているかどうかをSunJVMで確認できます。

残念ながら、これがApple JVMに当てはまるかどうかはわかりません。

Image's getCapabilities(GraphicsConfiguration).isAccelerated() を使用して、個々のイメージがハードウェアアクセラレーションされているかどうかを確認できます。

これをすべて言っても、私が見たすべてのドキュメント( これ を含む)は、BufferedImagenotハードウェアアクセラレーション。 Swingも、まさにこの理由から、ダブルバッファリングにVolatileImagesを使用するように変更されました。

2
Powerlord