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