• スポンサードリンク

EGLのeglReleaseThreadが動かへん端末がある・・・

Android NDK

今週は夏ばてのせいなのか頭と喉と首筋が痛いので今回は少し前の事を記事にします。考える気力が(-_-;)

いきなりですが、公式にAndroidのNDKでEGLが使える条件は、

  1. NDK付属の「STABLE-APIS.html」によると、NDKでのEGLサポートはAPI Level9以上(>Android2.3)と言う事になっています。
  2. 一方khronosのホームページでeglReleaseThreadのマニュアルを探すとEGLバージョン1.2以上言う事になっています。

ってのを見たらAPI Level9以上でEGLバージョン1.2以上が返って来たらeglReleaseThreadが使えるんやぁ〜って思いませんか?

でも動かへんねん

でもでもデモもそんなの関係ねぇ〜♪ API Level16(Android4.1.2)でEGL1.4でもeglReleaseThreadを使えないのが有りました。まぁAndroidではよくある事のような気もするんですけどね。

駄目な端末でeglReleaseThreadを呼び出すとそれ以降のEGL関係の呼び出しが軒並みずっこけるみたいです。ちゃんとデバッグしていないのでもしかしたら自分が使い方を間違えているだけなのかもしれないけど。
ネットをウロウロすると、非公式にはeglReleaseThreadはAndroid4.2以上と書いてあるところが有りました。ここ
でも、eglReleaseThreadに関係してそうなクラッシュの話がネットにいっぱいあるんですよね。

そもそも、eglReleaseThreadってなんやねん?

khronosのWebサイトでマニュアルを斜め読みしたところでは、スレッド毎に保持しているEGLステートをクリアするAPI・・・マルチスレッドでEGLを使うときのクリーンアップ関数みたいです。
どのスレッドでもいつでも呼んで良いし、1つのスレッドで複数回呼んでも良い。クリアされるのはエラーステート(eglGetErrorで取得可能)のようなスレッド毎に保持しているステートだけで、そうでないのは影響受けないし、contexts, surfaces, configuration listsのようなリソースも影響を受けない。
・・・と言う事らしいです。

とりあえずコード

初期化とかは省略して肝心の終了処理の部分を載せてみます。こんな感じ。NDKなのでC/C++ですからね。

変数名は想像して下さい(笑) そのまんまですけど。
そう沢山持っているわけでは無いですけど手元の機種ではGalaxyS3(SC-06D, Android4.1.2 EGL1.4)が駄目でした。他の子達は何事も無く皆無事に動いているので、またしてもお前か(●`ε´●)って言う気も・・・この間のMediaCodecInfo#getCapabilitiesForTypeに続けて2連チャンです。

17行目のeglReleaseThreadを呼び出した後からLogCatが一瞬にして

ってのに埋め尽くされました。しかもアプリ自体はハングアップしました。ANR様降臨 ガ━━(;゚Д゚)━━ン!!

あっでもハングアップとエラーメッセージ連発自体はアプリの実装由来かもしれないです。リリース版でコンパイルしたのでEGL/OpenGL|ES関係のエラーチェックは素通りなのが多いので。エラーが返って来た時点で自分で強制終了すればハングアップとエラーメッセージ連発は回避できそうですが、アプリとしては役に立ちません。
EGLの終了処理後にスレッド自体も終了して、次使うときにはまた最初から初期化しているのにぃ〜。shared_contextも使ってないのにぃ〜(●`ε´●)

解決策

eglReleaseThreadを呼び出さない。これに尽きます。たぶん(-_-;) 後は仮に前のステートが残ってても問題ないように常にEGL/OpenGL|ESをフルに初期化する事なのかな?でもええのか?
グルグル先生に聞いて出てきたeglReleaseThreadに関係してそうなクラッシュの話で解決策が載ってるのはなさそうでした。英語以外のは読んでないけど。

Androidのシステム内でも使ってるみたいだし、回避する方法があるとは思うんだよなぁ〜。テスト用のプロジェクトを作ればUSBでadb繋げるからデバッグ出来るんだけど、そこまでの気力が無い・・・まぁ昔は無かった訳だし入れてなかったし気にしないことにしよう(^o^)/誰か詳しい人教えて下さいm(__)m

と言う事で、今回はおしまい。
お疲れ様でした。

« »

  • スポンサードリンク

コメント