OpenGL ES 2.0のマルチスレッドの扱い

4,318 views
Skip to first unread message

ねこ

unread,
Apr 25, 2012, 8:20:31 AM4/25/12
to 日本Androidの会
はじめまして。

Android NDK で OpenGL ES 2.0 を使い、
メインスレッドで作ったテクスチャに、
サブスレッドで glTexSubImage2D を行いたいのですが、
テクスチャに反映されず透明になってしまい上手くいきません。

サブスレッドで eglCreateContext の引数にメインスレッドで生成した
ディスプレイやサーフェスやコンテキストを指定して、
それで生成したコンテキストを eglMakeCurrent に入れています。

EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
EGLContext context = eglCreateContext(g_display, g_config, g_context,
contextAttribs);
eglMakeCurrent(g_display, g_surface, g_surface, context);

動作確認は ISW11HT と Adreno SDK で行っております。
何かやり方が悪いのでしょうか? ご教授頂ければ幸いです。

Hiroaki GOTO as GORRY

unread,
Apr 25, 2012, 1:40:20 PM4/25/12
to android-g...@googlegroups.com

後藤 浩昭(GORRY)です。
ソースを読んだ結果での推測です。間違いあればご指摘を。

EGL10#eglMakeCurrent()は、最終的にはframework/base/opengl/libagl/egl.cppの
makeCurrent()を実行します。

> static int makeCurrent(ogles_context_t* gl)
> {
> ogles_context_t* current = (ogles_context_t*)getGlThreadSpecific();
> if (gl) {
> egl_context_t* c = egl_context_t::context(gl);
> if (c->flags & egl_context_t::IS_CURRENT) {
> if (current != gl) {
> // it is an error to set a context current, if it's already
> // current to another thread
> return -1;
> }

「指定したGLコンテキストを他のスレッドが所有している(Currentに
している)場合はエラー」ということになります。
通常、このGLコンテキストはGLSurfaceView内のGLThreadクラスを
実行しているスレッドが所有していて手放すことはないため、
他のスレッドがこのGLコンテキストを所有することはできないと
いうことになります。

他スレッドからGLコンテキストを使った処理を行いたい場合、
その処理をGLSurfaceView#queueEvent()で登録して、GLThreadの
スレッドにあとで実行してもらうという方法をとることになります。


In message <cc34282a-02d3-4b8f...@to5g2000pbc.googlegroups.com>
"[android-group-japan: 18024] OpenGL ES 2.0のマルチスレッドの扱い"
--
Hiroaki GOTO as "GORRY" : 後藤 浩昭
EMAIL: gorr...@gmail.com

ねこ

unread,
Apr 25, 2012, 10:33:49 PM4/25/12
to 日本Androidの会
後藤 浩昭様。

お答えありがとうございます。

すみません、説明事項で重要な部分が抜けておりました。
NativeActivity を使用している為、
GLSurfaceView 及び Java は使っていないのです。

それと GLコンテキストは、スレッド内で生成した物だけ
使える(他のスレッドで生成した物は使えない)との事は、
通常の OpenGL で言及されていた為、
サブスレッドで生成した物を使っています。
その際に eglCreateContext の第三引数に、
メインスレッドのコンテキストを指定する事で、
テクスチャなどの共有が出来るという話を聞いたので、
そちらはそれを指定しています。

NativeActivity で C++ 内から他のスレッドから
GLコンテキストを扱うにはどうしたらいいのでしょうか。

Hiroaki GOTO as GORRY

unread,
Apr 26, 2012, 10:26:53 PM4/26/12
to android-g...@googlegroups.com

後藤 浩昭(GORRY)です。

まず前回の返信に補足。libaglは「ビデオチップにOpenGLの
ハードウェアドライバがない場合に使用するソフトウェア
ドライバ」のようで、今のAndroid実機では使われることは
普通なさそうです。

エミュレータでは使用しているかもしれませんが、調べていません。

--

当方もOpenGL ESの使用はNDKがメインです。
NativeActivity/Java(GLSurfaceView)どちらも使用しています。
以前に実験で「複数スレッドからは扱えない」と結論づけて
使用しないようにしていたのですが、再度実験してみました。

eglCreateContext()の第3引数に他スレッドで作成したコンテキストを
渡して、共有コンテキストを得るところまでは成功しますが、
それでeglMakeCurrent()を行った時点でEGL_BAD_ACCESSが返ります。

なお、このエラーコードを返すのはAndroidフレームワーク側ではなく
ビデオチップドライバ側のようです。同等のAPI発行手順でWindows
(AngleProject)では成功するところからも、これはOpenGL ES(EGL)の
仕様上の制限ではなく、ドライバ側の実装上の制限ではないかと
思われます。

ちなみに、libaglでは共有コンテキストの中身は実質無効で
必ずエラーを返す実装になっていました。


In message <588ece7c-1279-4d9f...@t2g2000pbg.googlegroups.com>
"[android-group-japan: 18040] Re: OpenGL ES 2.0のマルチスレッドの扱い"
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja からこのグループにアクセスしてください。

ねこ

unread,
Apr 27, 2012, 7:46:32 AM4/27/12
to 日本Androidの会
なるほど、ドライバ側の制限でしたか…。
あくまで可能なのは共有のコンテキストまでで、
それを設定する所までは出来ないのですね。
これですっぱりと諦められて助かりました。

詳しく調べて頂きありがとうございました。
Reply all
Reply to author
Forward
0 new messages