OSDN Ticket Archive


Ticket #35749

El Capitanにて起動時にエラー発生

登録: 2015-11-18 01:07 最終更新: 2015-11-29 00:26

報告者:
yknk
担当者:
yknk
チケットの種類:
バグ
状況:
完了
コンポーネント:
MIDITrail Ver.1.2.x for Mac OS X
マイルストーン:
Version 1.2.2 for Mac OS X (完了済み)
優先度:
9 - 最高
重要度:
9 - 最高
解決法:
修正済み
ファイル:
なし

詳細

OS X 10.11 (El Capitan)にて MIDITrail Ver.1.2.1を起動すると、 次のエラーが発生してアプリを利用できない。

ERROR
Program error.
FILE: OGLPrimitive.mm
LINE:327
INFO: 00000000 00000000

チケットの履歴

2015-11-18 01:07 更新者: yknk
  • 新しいチケット "El Capitanにて起動時にエラー発生" が作成されました
2015-11-18 01:12 更新者: yknk
  • チケットの種類機能リクエスト から バグ に更新されました
2015-11-18 01:13 更新者: yknk
コメント

エラー発生時の処理ルート

エラー発生時の処理ルートは以下の通り。

[MTMainView thread_DrawScene]
[MTMainView thread_DrawProc]
OGLRenderer::RenderScene
MTSceneTitle::Draw
MTSceneTitle::Transform
MTLogo::Transform
MTLogo::_SetGradationColor
OGLPrimitive::UnlockVertex
glBufferSubData
ここでエラー発生
起動画面のMIDITrailロゴ描画処理で、頂点バッファの書き換えのため OpenGLのglBufferSubDataを呼び出したときにエラーが発生していた。 glGetErrorの返却値は1282(GL_INVALID_OPERATION)。

しかし、MTLogo::_SetGradationColorが戻り値を返さないメソッドとして定義されていたため、 検出されたエラーが握りつぶされてしまった。 OGLPrimitive::UnlockVertexが失敗したことで、ロックフラグがONのまま処理が続行した後に、 次の箇所でエラーを検出した。

[MTMainView thread_DrawScene]
[MTMainView thread_DrawProc]
OGLRenderer::RenderScene
MTSceneTitle::Draw
MTLogo::Draw
OGLPrimitive::Draw
ここでエラー検出
描画処理OGLPrimitive::Drawで、ロックフラグがONのままであったため、 プログラムエラーと判断してエラーメッセージを表示した。

2015-11-18 01:14 更新者: yknk
コメント

原因

El Capitan において、NSOpenGLViewの動作が変更されていた。 prepareOpenGLの呼び出しタイミングが非同期になったことで、 OpenGLの処理で異常が発生した。

Yosemiteまで

MIDITrail起動時の初期化処理で、メインウィンドウ表示を実行する時に prepareOpenGLが同期実行される。

El Capitan

MIDITrail起動時の初期化処理で、メインウィンドウ表示を実行しても、 prepareOpenGLが同期実行されない。 初期化処理が完了してイベントループに戻った後、 別のイベントでprepareOpneGLが実行される。

MIDITrail起動時の初期化処理において、メインウィンドウ表示の直後に シーンオブジェクトの生成を行っており、この中で頂点バッファを生成していた。 El Capitanの環境では、メインウィンドウ表示でprepareOpenGLは実行されず、 OpenGLコンテキストが生成されない。この状態で頂点バッファを生成することになった。 そしてOpenGLコンテキスト生成後の頂点バッファ書き換え処理でエラーが発生した。

参考情報:
OSX El CapitanでのNSOpenGLViewの挙動の変化
http://ysflight.in.coocan.jp/programming/macosx/20151004/j.html
2015-11-18 01:15 更新者: yknk
コメント

解析メモ

MTMainView::prepareOpenGLが実行されるタイミングは以下の通り。

Yosemiteの場合

ウィンドウ表示を実行する時点でprepareOpenGLが同期実行されていた。

[NSApplication run]
[NSApplication finishLaunching]
...
MIDITrailApp::Initialize
MIDITrailApp::_CreateWindow
[MTMainWindowCtrl showWindow]
[NSWindowController showWindow]
...
[NSOpenGLContext makeCurrentContext]
[MTMainView prepareOpenGL]

El Capitanの場合

イベントループに戻った後でprepareOpneGLが実行される。

[NSApplication run]
[NSApplication nextEventMatchingEvnetMask:untilDate:inMode:dequeue]
...
[NSOpenGLContext makeCurrentContext]
[MTMainVIew prepareOpenGL]

2015-11-18 01:15 更新者: yknk
コメント

対策

シーンオブジェクト生成を、prepareOpenGLが実行された後に移動する。 なお、本件のEl Capitan環境での検証のため、開発環境をXcode7に移行した。 (#35750 OS X版の開発環境をXcode7に変更)

applicationWillFinishLaunching

OpenGLコンテキスト準備完了通知を受け取るよう、通知先を登録する。

onPreparedOpenGL

OpenGLコンテキスト準備完了通知受信処理を新規追加。 MIDITrailApp::OnPreparedOpenGLを呼びだす。

prepareOpenGL

OpenGLコンテキスト準備完了を通知する処理を追加。

MIDITrailApp::Initialize

シーンオブジェクト生成処理_CreateSceneを削除。 MIDITrailApp::OnPreparedOpenGLに移動。

MIDITrailApp::OnPreparedOpenGL

OpenGLコンテキスト準備完了イベント処理を新規追加。 シーンオブジェクト生成とシーン描画開始(スレッド起動)を行う。 コマンドライン処理を起動直後の1回のみ実行する。

MIDITrailApp::Run

シーン描画開始(スレッド起動)を削除。 これにより本メソッドは何も処理を行わなくなった。

MIDITrailApp::_ChangeWindowSize

ウィンドウサイズ変更時に、メインウィンドウを作成しなおしたとき 非同期でonPreparedOpenGLが実行されるため、 シーンオブジェクト生成とシーン描画開(スレッド起動)を削除する。 この処理は、MIDITrailApp::OnPreparedOpenGLに任せる。

MIDITrailAppクラス

コマンドライン処理済みフラグm_isCmdLineProccessedを追加。

MTLogo::_SetGradationColor

戻り値を返すように修正する。

2015-11-18 01:16 更新者: yknk
  • 解決法なし から 修正済み に更新されました
2015-11-23 00:18 更新者: yknk
コメント

対策(追加)

MIDITrailApp::OnDropFile

ファイルドロップイベント発生タイミングがOpenGL準備完了前であれば、処理をスキップする。 ファイルドロップイベントは、アプリアイコンにファイルをドロップしてアプリが起動した時にも発生する。 しかしOnDropFileが呼び出されることで、OpenGL準備前にファイル読み込みとシーンの生成処理が実行されてしまう。 ファイルドロップによるアプリ起動については、コマンドライン解析処理に任せる。

これまで、コマンドラインでファイルパスを指定して起動した場合、 コマンドライン解析処理とドロップイベントにより、二回のファイル読み込みが発生していたようだ。 しかし無駄な処理をしているだけで、エラーにはならない。

2015-11-29 00:26 更新者: yknk
  • 状況オープン から 完了 に更新されました
  • チケット完了時刻2015-11-29 00:26 に更新されました

添付ファイルリスト

添付ファイルはありません