任务单 #35749

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

开放日期: 2015-11-18 01:07 最后更新: 2015-11-29 00:26

报告人:
属主:
类型:
状态:
关闭
优先:
9 - Highest
严重性:
9 - Highest
处理结果:
Fixed
文件:

Details

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

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

任务单历史 (3/9 Histories)

2015-11-18 01:07 Updated by: yknk
  • New Ticket "El Capitanにて起動時にエラー発生" created
2015-11-18 01:12 Updated by: yknk
  • 类型 Update from Feature Requests to Bugs
2015-11-18 01:13 Updated by: 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 Updated by: 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 Updated by: 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 Updated by: 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 Updated by: yknk
  • 处理结果 Update from to Fixed
2015-11-23 00:18 Updated by: yknk
评论

対策(追加)

MIDITrailApp::OnDropFile

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

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

2015-11-29 00:26 Updated by: yknk
  • 状态 Update from 开启 to 关闭
  • Ticket Close date is changed to 2015-11-29 00:26

Attachment File List

No attachments

编辑

Please login to add comment to this ticket » 登录名