我們?cè)诿嬖嚨倪^(guò)程中經(jīng)常被問(wèn)到的一個(gè)問(wèn)題就是Draw call职辨,那么Draw call是什么、到底有多重要戈二、哪些因素會(huì)影響它舒裤、我們?cè)趺慈?yōu)化它?
1. Draw call是什么觉吭?
Draw call是CPU對(duì)底層圖形繪制接口的調(diào)用命令GPU執(zhí)行渲染操作腾供,渲染流程采用流水線實(shí)現(xiàn),CPU和GPU并行工作鲜滩,它們之間通過(guò)命令緩沖區(qū)連接伴鳖,CPU向其中發(fā)送渲染命令,GPU接收并執(zhí)行對(duì)應(yīng)的渲染命令徙硅。
2. 到底有多重要榜聂?
如果Draw Call的數(shù)量太多,CPU就會(huì)把大量時(shí)間花費(fèi)在提交Draw Call 上嗓蘑,造成CPU的過(guò)載须肆,會(huì)影響幀率。建議Draw call次數(shù)保持在50以下桩皿,總之越少越好豌汇。
3. 哪些因素會(huì)影響它?
要減少Draw call次數(shù)泄隔,就需要批處理拒贱,把小的Draw Call合并到一個(gè)大的Draw Call中。但是我們批處理的時(shí)候往往會(huì)被阻斷梅尤,這里我們就要搞清楚哪些情況會(huì)被阻斷:
- Label
- Mask
- 粒子
- And so on
4. 我們?cè)趺慈?yōu)化它柜思?
這里我們舉幾個(gè)例子來(lái)看一下,用cocos creator 2.4.2做參考(不同引擎不同版本可能結(jié)果不一樣)巷燥。
我們新建一個(gè)空?qǐng)鼍吧呐蹋l(fā)現(xiàn)Draw call是1
-
Label + Sprite
一個(gè)Item.jpg
如上圖我們添加了一個(gè)item(Label + Sprite)發(fā)現(xiàn)Draw call變成3了,這很好理解缰揪,圖片一次陨享,文字一次。但這個(gè)不是我們想要的钝腺,照這樣發(fā)展下去抛姑,2個(gè)item有5次,3個(gè)item有7次艳狐。定硝。。毫目。那么100個(gè)就有201次蔬啡,這很恐怖了,如下圖:
超多drawcall.jpg
怎么優(yōu)化呢诲侮?
我們可以讓這文字也變成圖片,和這張圖片合在一起處理箱蟆,這時(shí)候就可以用Bitmap font或者TextAtlas去代替文字沟绪,不管加多少個(gè)Item,Draw call次數(shù)都不會(huì)增加空猜,如下圖:
處理后.jpg -
Sprite + Mask + Sprite
我們?cè)诳請(qǐng)鼍爸袆?chuàng)建一個(gè)空節(jié)點(diǎn)绽慈,然后給這個(gè)節(jié)點(diǎn)上面添加一個(gè)Mask組建,發(fā)現(xiàn)Draw call次數(shù)變成3了辈毯,也就是說(shuō)一個(gè)Mask有兩次Draw call
一個(gè)Mask.jpg
但只是這樣嗎坝疼?顯然不是,請(qǐng)看下面兩張圖:
這兩張圖片其他什么都一樣漓摩,只是Mask在節(jié)點(diǎn)樹(shù)中的位置發(fā)生了變化裙士,導(dǎo)致了Draw call次數(shù)增加。
這種情況還比較好處理管毙,我們盡量不要讓Mask在Sprite之間腿椎。
如下圖,像Mask+Sprite這種每增加一個(gè)Item Draw call就會(huì)增加3夭咬,比Label + Sprite還恐怖啃炸,這種情況又該怎么處理呢?