2016-03-21 33 views
1

要するに、OpenGL ES 2.0で最も効率的な方法でFBOや別のテクスチャにコピーする必要があるOpenGLテクスチャがあります。OpenGL ES 2.0 - テクスチャをフレームバッファに効率的にコピーする方法

現時点では、最初のテクスチャを単にFBOに描画しています。

もっと効率的な方法がありますか?例えば。ピクセルデータをRAMに戻してから別のテクスチャにバッファリングすることを含まない何らかの種類のピクセルコピー - ES 2.0プロファイル内。

あなたにコンテキストを与える - このビデオは、関連するレンダリングされます。

私はLibVLCからビデオフレームデータをバッファリングされているOpenGLのテクスチャを持っていますが、原因私のアプリ間のタイミングの問題にレートとデコーダのリフレッシュレートを再描画、そのOpenGLのテクスチャに更新するフレームがない場合は、&を更新するフレームなしで画面にテクスチャを描画すると、非常に奇妙なことになる可能性があります。以前のフレームのデータを含む代わりに、それ自体の奇妙なイメージが描画されますスペースインベーダーのように)?? - なぜ私は前のフレームのコンテンツをキャッシュする必要があるのですか?

具体的には、AndroidのSurfaceTextureを作成するために使用されるOpenGLテクスチャです。このテクスチャのコンテンツを更新するためにupdateTexImageとreleaseTexImageを手動で呼び出す必要があります。次に、それを描いた。私がそれを解放しなければ、新しいフレームをそれに更新することはできません。私がそれをリリースすれば、同じフレームを複数回再描画することはできません。それはデコーダが自由に書き込むことができるように更新されたらテクスチャをキャッシングするように私に導かれました&私は再び描画するときに私はまだ前のフレームを持っています&まだ更新されていません。

ありがとうございました。

+0

私は最後に、onFrameAvailableコールバックがリリースしてから更新し、それを可能にするためにGLContentを与えることによって、Android SurfaceTextureのupdateTexImageメソッドとreleaseTexImageメソッドをアプリケーション内で処理する方法を解明して問題を修正しました。もうキャッシュする必要はありませんが(私は!)、私はまだどんな答えにも興味があります。 –

+0

と同じであれば、ソリューションとして回答を投稿する必要があります。 –

+0

'glCopyTexImage2D'はどうですか? – elect

答えて

0

このソリューションは、Android SurfaceTextureと正しくインターフェースする方法を試した結果、コンテンツを完全にキャッシュする必要がなくなりました。

OpenGL ES 2.0で効率的なテクスチャコピーに関する回答を共有したい人は、私のオリジナルの質問にぴったりです。興味がある人々のために

が、これは私がやったことです:Android上でビデオをレンダリングするための

マイGLPaintクラスはSurfaceTextureインスタンスが含まれている、それがJOGL OpenGLのテクスチャ(それはIDです使用して)から作成しています - これは、描画するために私を可能にします私のGLPaint.paint関数の一部としてのテクスチャ。

このGLPaintは、SurfaceTexture.OnFrameAvailableListenerインターフェイスのonFrameAvailableメソッドを実装しています。私は、最初のフレームが '書かれた'ときにフラグを立てるためのプライベートブール値を持っています。これは、SurfaceTextureを早めに解放するのを避けるために必要です。

クラスGUIThreadLockは、ReentrantLockの拡張です。追加のデバッグ情報と静的なシングルトンを作成するために拡張しました。私のUIのスレッドのための私の 'one-in-one out'コントローラのこのロックは、一度に1つのスレッド(通常はメインのレンダラルーパーのみ)でアクティブになりますが、OpenGLコンテキストのバインドまたはアンバインドを処理しますロック所有者スレッドは、それぞれロックを取得して放棄するたびにロックします。

@Override 
    public void onFrameAvailable(SurfaceTexture pSurfaceTexture) 
    { 
     try 
     { 
      GUIThreadLock.acquire(); 
      if(written) 
      { 
       pSurfaceTexture.releaseTexImage(); 
      } 
      pSurfaceTexture.updateTexImage(); 
      written = true; 
     } 
     finally 
     { 
      GUIThreadLock.relinquish(); 
     } 
    } 

これは、新しいフレームの準備ができると、SurfaceTextureは新しいものに古いもの&のアップデートをリリースしていることを意味します - それは、その後、私は次までの映像を描画したい任意のポイントの現在のフレームをバッファリングされていますフレームが準備完了です。GUIThreadLockは、Drawing中にSurfaceTextureがコンテンツを更新するのを防ぎますが、コールバックスレッドが実際にここで更新を実行できるようにGLコンテキストを取得します。

私の再描画スレッドでは、アプリケーションを描画する前にGUIThreadLockが必要になるため、GLコンテキストが保護され、フレーム更新とフレーム描画の関係が強化されます。

+0

これはクールな解決策ですが、FBOに最初の画像を描画する方が効率的であるという証拠はありますか? – Andreas

+0

テクスチャに裏打ちされたFBOを使用していた場合は、そのTextureIDを渡してここに記載されているAndroid SurfaceTextureオブジェクトを作成できます。同じ方法で動作しますが、TextureではなくFBOを与えます。データのコピーに関しては、私は表面的なテクスチャからのデータをコピーするというアサーションだけを示しています(OpenGLテクスチャを別の見方で覚えています)。フレームあたりの操作数が増えます。上記の解決策は、AndroidSurfaceのテクスチャをどのように統合するかに関する手続き的な解決策です。 –

+0

私は "フレームあたりのより多くの操作"に同意します。それが効率的な定義であれば、おそらくより効率的な解決策になりました。スレッドコンテキストの切り替えによるオーバーヘッドのために高速であるかどうかはわかりません。私は各ソリューションのパフォーマンス結果を知りたいと思います。 – Andreas

関連する問題