web-dev-qa-db-ja.com

TextureView対GLSurfaceViewまたはEGL14でGLSurfaceViewを使用する方法

EGLと混同しています。

私のGLSurfaceViewはEGLContextを作成します。次に、共有コンテキストを作成します。次に、EGLExtensionを使用する必要があります。

私が使用しなければならないメソッドは呼び出されます(> = API18):

EGLExt.eglPresentationTimeANDROID(Android.opengl.EGLDisplay display, Android.opengl.EGLSurface surface, long time);

問題は、GLSurfaceViewがjavax.microedition.khronos.egl.EGLContextのみを作成することです。

これは、GLSurfaceViewを使用しないことを教えてくれます。そこで、独自のEGLを処理する必要があるという違いを除いて、少し似たTextureViewを試してみました。これはその目的に適しています。

しかし:TextureViewは遅く、少なくともそのように見えたため、メソッドプロファイラーでいくつかの図を記録しました。

ここに独自のEGL処理を備えたTextureView: enter image description here 上部のスレッドは、中央のスレッドを起動するクロックで、TextureViewにレンダリングされます。メインのスレッドはその後、TextureViewを再描画するために呼び出されます。

...そしてここでは、独自のEGL処理を備えたGLSurfaceViewクロックが今度は真ん中にあり、上部のスレッドを呼び出して、画像をフレームバッファーにレンダリングします。レンダリングするビューを要求します。 enter image description here

GLSurfaceViewを使用すると、短い外観で既に確認できるように、TextureViewを使用した場合よりも見た目がきれいになります。

どちらの例でも、画面には何も表示されず、同じシェーダーでまったく同じメッシュをレンダリングしました。

私の質問へ:GLSurfaceViewをEGL14コンテキストで使用する方法はありますか?

私は何か間違ったことをしましたか?

25
andre

おそらくあなたがしたいことは、プレーンな SurfaceView を使うことです。

ここに短いバージョンがあります:

  • SurfaceViewにはSurfaceViewの少しの偽物の2つの部分があります。 Surfaceはサーフェスコンポジター(SurfaceFlinger)に直接渡されるため、OpenGLで描画する場合、オーバーヘッドは比較的少ないです。これにより高速になりますが、Surfaceが1つのレイヤーにあり、ビューベースのUIが別のレイヤーにあるため、ビュー階層で正しく機能しません。
  • TextureViewにも2つの部分がありますが、あなたが描く部分は舞台裏で行われます(そこにSurfaceTextureが入ります)。フレームが完了すると、描いたものがビューレイヤーにブリットされます。 GPUはこれをすばやく実行できますが、「一部の作業」は「作業なし」よりも常に遅くなります。
  • GLSurfaceViewは、すべてのEGLセットアップとスレッド間メッセージングを行うラッパークラスを備えたSurfaceViewです。

編集:長いバージョンが利用可能です ここ

GL/EGLのセットアップとスレッド管理を自分で行うことができる場合(現在、TextureViewで実行している場合は、明らかにそれが可能です)、プレーンなSurfaceViewを使用する必要があります。

以上のことから、元のコードをGLSurfaceViewで動作させることができるはずです。 GLSurfaceView自体からではなく、GLSurfaceViewと共有されているEGLコンテキストでeglPresentationTimeANDROID()を呼び出したいので、GLSurfaceViewは内部的にEGL10を使用しています。コンテキストを共有するために重要なのは、コンテキストの構成に使用されるEGLインターフェースのバージョンではなく、コンテキストクライアントのバージョン(GLES2とGLES3など)です。

Grafika でこのすべての動作の例を見ることができます。特に:

  • 「表示+キャプチャカメラ」は、GLSurfaceView、カメラ、およびビデオエンコーダーを使用します。 EGLコンテキストが共有されていることに注意してください。この例は、主に意図的にGLSurfaceViewと共有EGLコンテキストを使用しようとしているため、複雑でやや苦痛です。 (更新:注 この問題 共有コンテキストの競合状態について。)
  • 「ビデオの再生(TextureView)」と「Basic GL」は、実際のTextureViewを示しています。
  • 「Record GL app with FBO」は、プレーンなSurfaceViewを使用します。
47
fadden

Faddenに感謝!期待通りに動きました。

同様のことをすることを考えているすべての人に:

(GL)SurfaceViewを使用して画像をレンダリングすることには、利点と欠点があります。

上記の投稿での私のテスト結果では、画面上にレンダリングされた画像以外のものはありません。画面に他のUI要素がある場合、特にそれらが頻繁に更新される場合は、(GL)SurfaceViewを選択するという私の選択を再検討する必要があります。

SurfaceViewは、Android Windowsystemに新しいウィンドウを作成します。その利点は、SurfaceViewが更新されると、このウィンドウのみが更新されることです。UI要素(別のウィンドウにある)をさらに更新すると、 openglはマルチスレッドの描画を適切に処理できないため、ウィンドウシステムの場合)、両方の更新操作でブロックされます(特に、UI描画がハードウェアでサポートされている場合)。

そのような場合は、TextureViewを使用した方がよい場合があります。これは、Android Windowsystemの別のウィンドウではないためです。したがって、ビューを更新すると、すべてのUI要素も更新されます。(おそらく)すべて1つのスレッドで。

お役に立てれば幸いです。

8
andre