1. 內(nèi)存管理
Cocos2dx是通過引用計數(shù)方式管理內(nèi)存,主要通過兩種方式實現(xiàn)否纬。
1.1 手動內(nèi)存管理
手動retain和release
1.2 autorelease
創(chuàng)建一個對象后,可以使用autorelease()方法放入自動回收池,每一幀結(jié)束的時候自動release。函數(shù)調(diào)用關(guān)系為:
- director->mainLoop()
- PoolManager:getInstance->getCurrentPool->Clear()
- obj->release()
問題:
- 發(fā)生時機在幀結(jié)束時期性含,release出錯難定位。
- 如果一幀創(chuàng)建大量對象鸳惯,會導(dǎo)致釋放池性能下降商蕴。
2. 渲染機制
Cocos2dx在每一幀進行一次渲染,mainloop()方法的drawScene()方法芝发,先清除渲染狀態(tài)绪商,然后調(diào)用_runningScene->render()方法。render()里使用visit()方法辅鲸,用sortAllChildren()(按LocalZOrder和OrderOfArrival排序)對子節(jié)點排序格郁,通過調(diào)用draw函數(shù),首先繪制LocalZOrder<0的節(jié)點独悴,在繪制自身例书,最后繪制LocalZOrder>0的節(jié)點。draw函數(shù)里面并沒有做實際的渲染工作刻炒,而是初始化渲染命令决采,添加到對應(yīng)的渲染隊列中。最后回到_runningScene->render()中執(zhí)行Renderer::render()方法落蝙。
Renderer::render()方法中织狐,對_renderGroups(_renderGroups是存儲RenderQueue的容器,RenderQueue類實質(zhì)是一個存儲了5種渲染命令的容器)里的每個渲染隊列執(zhí)行sort方法排序筏勒,根據(jù)其GlobalZorder從小到大進行排序,對GZOrder小于0的渲染命令旺嬉、GZOrder大于0的渲染命令按ZOrder從小到大進行排序管行。此時沒有對GZOrder等于0的渲染命令排序,因為這些渲染命令的添加是按照所屬的Node的LocalZOrder順序添加的邪媳,即已經(jīng)排好序捐顷,無需再次排序荡陷。
排序后執(zhí)行visitRenderQueue(_renderGroups[0])(),該方法是按隊列里命令分類的順序迅涮,依次對每個分類的每個命令執(zhí)行processRenderCommand方法废赞。
processRenderCommand方法遍歷隊列內(nèi)的每個分類,把命令加到容器中叮姑。在當前分類的命令都被遍歷之后唉地,執(zhí)行flush()方法,該方法主要是調(diào)用了drawBatchedTriangles()方法传透。
drawBatchedTriangles()會判斷批量渲染的條件是否成立耘沼,主要是比較當前命令材質(zhì)ID和上個命令材質(zhì)ID。
總結(jié)
渲染是在每幀結(jié)束前進行的朱盐;渲染之前是把每幀的所有元素的繪制用命令統(tǒng)一進行存儲群嗤,在渲染時讀取這些命令,進行繪制兵琳;渲染時還會進行批量繪制的判斷狂秘,這能有效降低DrawCall值。
3. 程序開始和結(jié)束
3.1 開始
AppDelegate::applicationDidFinishLaunching()里的runWithScene躯肌。
3.2 結(jié)束
mainloop里的_purgeDirectorInNextLoop判斷
3.2.1 _purgeDirectorInNextLoop何時改變
- director調(diào)用end()函數(shù)者春。
- popScene,無場景的時候也會調(diào)end羡榴。
3.2.2 purgeDirector()做了什么
- 清理定時器
- 回收當前場景
- 銷毀緩沖區(qū)
- 執(zhí)行g(shù)lView的end()函數(shù)