cocos2d + 非同期 コメント付き

30
非同期 坂本一樹 @splhack

Transcript of cocos2d + 非同期 コメント付き

Page 1: cocos2d + 非同期 コメント付き

非同期

坂本一樹@splhack

Page 2: cocos2d + 非同期 コメント付き

cocos2d + 非同期

Page 3: cocos2d + 非同期 コメント付き

Loading

Page 4: cocos2d + 非同期 コメント付き

Loading.......

Page 5: cocos2d + 非同期 コメント付き

ローディングで画面がとまる

非同期で解決

Page 6: cocos2d + 非同期 コメント付き

非同期とは?

Page 7: cocos2d + 非同期 コメント付き

@yuroyuro: 31 May 2011

『非同期って、「オマエ同期入社じゃねーしwww 中途乙www」とか言われてぼっちになることですか』

非同期とは

http://twitter.com/#!/yuroyoro/status/75399664496680960

Page 8: cocos2d + 非同期 コメント付き

cocos2d メインループ

cocos2d デフォルトでCADisplayLink

RunLoopベース

非同期話の前に、メインループの話。cocos2dでもRunLoopベース。

Page 9: cocos2d + 非同期 コメント付き

CADisplayLink とは?

ディスプレイのリフレッシュに同期してRunLoopでイベントを発生させる代物

Page 10: cocos2d + 非同期 コメント付き

ディスプレイのリフレッシュ?

VSYNC

Page 11: cocos2d + 非同期 コメント付き

VSYNC

オブジェクトを動かしているシーンで、VSYNC無視して画面更新すると、オブジェクトがぶったぎれて見える

Page 12: cocos2d + 非同期 コメント付き

VSYNC

Vertical Synchronizing signal

垂直同期信号

Page 13: cocos2d + 非同期 コメント付き

ブラウン管テレビ 走査線

VRAMから読みだした絵をブラウン管に反映する

垂直同期信号って何? ブラウン管テレビの時代までさかのぼりますビームが左上から右下にかけて徐々に動いて、VRAMをブラウン管に反映していく一番下まで行って、一番下から一番上にもどるとこを垂直帰線区間。この間、絵は更新されない

Page 14: cocos2d + 非同期 コメント付き

VSYNC

垂直帰線区間中に描画するために垂直同期信号に同期させる

ビームが戻る垂直帰線区間内に画面を更新させるためにVSYNCは存在する垂直帰線区間外にVRAMを更新すると残念なことになる。iPhoneでも基本同じ。ブラウン管じゃなくて液晶ディスプレイ。

Page 15: cocos2d + 非同期 コメント付き

CADisplayLink

RunLoopがVSYNCに同期

CADisplayLinkを使うと、RunLoopがVSYNCに同期してループする

Page 16: cocos2d + 非同期 コメント付き

CADisplayLink

iOSでは 1/60秒

16.666ミリ秒

60FPS

1回のループの時間が1/60秒

Page 17: cocos2d + 非同期 コメント付き

1/60秒以上の仕事

次のVSYNCまで待機

1/60 → 2/60(1/30) → 3/60(1/20)→ 4/60(1/15) → ...

フレームレート低下!

1/60 ぬめぬめ動く

Page 18: cocos2d + 非同期 コメント付き

データをロード

RunLoopの実行を止めてしまう(Blocking)

データをロードしてRunLoopをブロックフレームレート低下どころの話ではない画面止まっちゃう

Page 19: cocos2d + 非同期 コメント付き

データをロード

RunLoopの実行を止めてしまう(Blocking)

完全なる悪

データをロードしてRunLoopをブロックフレームレート低下どころの話ではない画面止まっちゃう

Page 20: cocos2d + 非同期 コメント付き

データを非同期でロード

RunLoopの実行を妨げない

画面停止しない

完全なる善

Page 21: cocos2d + 非同期 コメント付き

cocos2dでテクスチャを非同期ロード

CCTextureCache- (void)addImageAsync:target:selector:

まずやっかいなのがテクスチャを非同期で読み込む方法。でもcocos2dだと簡単です。

Page 22: cocos2d + 非同期 コメント付き

addImageAsyncを実際にどう使うか、この本を読んでいただくか、ぐぐってもらうとして

Page 23: cocos2d + 非同期 コメント付き

addImageAsync 実装

•スレッド起動•起動したスレッド上でGL APIを 呼ぶためのコンテキストを準備 (EAGLContext sharegroup)

どういう実装になっているか

Page 24: cocos2d + 非同期 コメント付き

addImageAsync 実装

•イメージデータ読み込み•OpenGL ES テクスチャに変換•glTexImage2D (準備したGLコンテキストが実現)

通常メインスレッド以外でOpenGL ES APIを呼び出せば例外発生

Page 25: cocos2d + 非同期 コメント付き

addImageAsync 実装

•メインスレッドで コールバック呼び出し

Page 26: cocos2d + 非同期 コメント付き

メインループを止めない!

“ 極論をいえば、ユーザーインターフェースの更新など メインスレッドで実行しなければならない処理だけ RunLoopおよびMain Queueで実行し、それ以外の処理は Global Queueまたは後述のSerial Queueで実行すべし ”

iOS 4プログラミングブック マルチスレッドの章

Page 27: cocos2d + 非同期 コメント付き

Grand Central Dispatch

GCDを使おう!

何はなくとも iOS 4 以降専用

Page 28: cocos2d + 非同期 コメント付き

Grand Central Dispatch

Global QueueSerial Queue

addImageAsync 呼び出しは安全?

安全

ただし、コールバックは呼び出し元ではなく、メインスレッドで呼び出される

Page 29: cocos2d + 非同期 コメント付き

Grand Central Dispatch

iOS 4プログラミングブックの第5章をぜひ読んでくださいませ

Page 30: cocos2d + 非同期 コメント付き

おしまい