WebGL離屏畫不出來
原因:
當前的GLContext不是預期的孵淘,導致FBO綁定的不對
繪制某一張圖時時黑色的
原因:
WebGL和ES2中NPOT(non-power-of-two)的紋理并不是完全支持蒲障,NPOT的紋理環(huán)繞方式只能用GL_CLAMP_TO_EDGE,紋理過濾只能用GL_NEAREST或GL_LINEAR瘫证,且不能用mipmap揉阎。如果紋理參數(shù)設(shè)置了不支持的類型,shader在采樣時會直接輸出黑色背捌,且無任何報錯毙籽。
進入小游戲屏幕一直閃
原因:JS的不合理調(diào)用,開發(fā)商在適配屏幕比例后會一直設(shè)置寬高并清空FBO毡庆,導致閃屏坑赡。
WebGL畫不出某一張圖像
原因:我們的紋理數(shù)據(jù)默認是預乘Alpha的。WebGL可以設(shè)置紋理存儲方式為unPremultiplyAlpha么抗,這時要把紋理數(shù)據(jù)的alpha通道逆預乘毅否,才能保證shader中輸出的結(jié)果正確。
WebGL渲染偶先字體亂碼
原因:在切換場景時乖坠,WebGL紋理對象被釋放搀突,但JS GC時刪除紋理的操作命令發(fā)生在了離屏Canvas2D上下文,導致刪除了有用的紋理(舉例該紋理句柄為7號)熊泵,之后離屏Canvas2D在創(chuàng)建新的紋理時仰迁,OpenGL會從復用池里返回句柄7號,這導致JS在操作7號紋理時顽分,其實GPU上的紋理并不是開發(fā)商預期的徐许。
WebGL渲染黑屏
原因:WebGL綁定FBO或者RBO時,會傳一個Undefined來回到默認的RBO卒蘸。這時本地解析JSObject時會解成0雌隅,這在OpenGL中相當于解綁了FBO翻默。所以當JS調(diào)用bindFramebuffer/bindRenderbuffer時,JS傳Undefined恰起、null Native會綁定FBO\RBO為默認對象修械。
渲染圖像花屏
原因:在JS中,開發(fā)商在Canvas2D的環(huán)境創(chuàng)建了JSImage,但在WebGL環(huán)境也使用了检盼,由于在Native兩種環(huán)境不屬于同一個GLContext肯污,改成共享紋理解決。
復用紋理黑屏
原因:復用紋理使用glCopyTexSubImage2D, 復制的目標紋理要有內(nèi)存吨枉,不能只有句柄蹦渣。
OpenGL的局部更新操作,都要求目標對象已經(jīng)有內(nèi)存空間貌亭。
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glActiveTexture(GL_TEXTURE0);
targetTexture->resetTextureStorage();
targetTexture->bindToTarget(bindTarget);
glTexImage2D(bindTarget, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glCopyTexSubImage2D(target, level, 0, 0, 0, 0, width, height);
glBindFramebuffer(GL_FRAMEBUFFER, oldFbo);
glBindTexture(GL_TEXTURE_2D, targetTexture->textureId());
Draw call Crash
原因:頂點數(shù)據(jù)或索引數(shù)據(jù)傳的有問題, 上下文被污染柬唯,其他上下文的操作修改頂點數(shù)據(jù),導致頂點數(shù)據(jù)非預期圃庭。
畫出的紋理不對锄奢,不是目標紋理,而是上一幀用到的紋理
原因:用戶創(chuàng)建了多個sharedCanvas冤议,但SharedCanvas只支持單例斟薇,所以只有第一個有對應的GPU紋理,由于我們的紋理是懶加載恕酸,當數(shù)據(jù)源沒有數(shù)據(jù)時堪滨,沒有繼續(xù)調(diào)用TexImage2d,bindTexture, 導致這一幀的綁定紋理是上一幀的。改為解綁解決蕊温。
JS引擎設(shè)置低于60的幀率時袱箱,渲染是閃屏
原因:Egret引擎的做法是在60幀的RenderTicker之上,自己封裝一個調(diào)用Ticker, skip幀來達到控制幀率的效果义矛。由于WebGL默認是preserveDrawingBubffer=false, 所以有DrawCall的話发笔,在Skip的時間里,native是一直保持空rbo的狀態(tài)凉翻。
Draw Call Crash & 模型扭曲
原因:JS傳過來的多個TypedArray是基于同一個ArrayBuffer做不同偏移得到的了讨,而Native在解TypedArray指針時沒有加上這個偏移量,導致從加載到OpenGL Buffer內(nèi)容不符合預期制轰,模型頂點的位置前计、紋理坐標全是錯誤數(shù)據(jù),多次調(diào)用Draw Call后垃杖,由于頂點數(shù)據(jù)不符合預期男杈,導致GPU driver IOAF error code4 (GPU Hang Error).
轉(zhuǎn)場動畫黑屏、花屏
原因:在JS層傳錯了FBO ID调俘,導致上屏的FBO COLOR_ATTACHMENT的RBO被改成錯誤的伶棒。
轉(zhuǎn)場動畫后渲染黑屏
原因:在轉(zhuǎn)場后開發(fā)商使用WebGL解綁WebGL RBO旺垒,由于native會判斷如果是-1的話綁定默認的RBO。
但從JSC取值是是取double類型肤无,OpenGL傳參時是GLuint先蒋,double的-1轉(zhuǎn)無符號是0,導致錯誤舅锄。
渲染偶現(xiàn)的黑屏鞭达、花屏,報錯Execution of the command buffer was aborted due to an error during execution.
原因:開發(fā)商記住了編譯后的的uniform皇忿、vertexAttrib的slot, 并在之后使用。
在iOS的PVR架構(gòu)GPU下坦仍,一些沒有用到的shader變量會被優(yōu)化掉鳍烁,開發(fā)商會一直試圖對一個不存在的Uniform、vertexAttrib傳值繁扎,而在Native解他們的slot時幔荒,會導致解除的ID不代表真正想要的那個Uniform、vertexAttrib梳玫。
開發(fā)商一直對shader變量傳錯誤的值爹梁,導致Execution of the command buffer was aborted due to an error during execution.
錯誤。
解決方案:
每次寫shader變量時確認是否可用提澎。
內(nèi)存問題
原因:開發(fā)商會出現(xiàn)不主動調(diào)delete刪除OpenGL對象姚垃,導致大量OpenGL對象堆積在GPU,這部分的內(nèi)存占用是算在VM里的盼忌,其實CPU的占用并不多积糯。
解決方案:
在GC時主動刪除OpenGL對象解決。
渲染偶現(xiàn)的Crash
原因:為了優(yōu)化內(nèi)存管理谦纱,當JS GC時我們會刪除對應的OpenGL對象看成,GC回收不可控.
當deleteBuffer后,Buffer在GC之前跨嘉,buffer的ID由OpenGL復用返回給了其他createBuffer川慌,會導致GC時刪除的是有用的Buffer, 導致頂點數(shù)據(jù)錯誤,最終導致Crash.
解決方案:
deleteBuffer后清除本地的管理類解決祠乃。
渲染偶現(xiàn)的花屏
原因:為了優(yōu)化內(nèi)存管理梦重,當JS GC時我們會刪除對應的OpenGL對象,GC回收時機不可控.
但開發(fā)商預期在createTexture返回的對象跳纳, 在BindTexture后忍饰,即使在GC后已綁定的texture依然可用,這是WebGL的一個特征寺庄。
解決方案:
優(yōu)化了內(nèi)存管理釋放規(guī)則解決艾蓝。
小游戲顯存中存在重復的紋理
原因:開發(fā)商的一些不規(guī)范行為會導致顯存中存在重復的紋理力崇,如第三方引擎會自動將小游戲所用的圖像資源合成一個大的紋理圖集,這樣方便管理和提高渲染效率赢织,但開發(fā)商在JS層持有住了所有圖像亮靴,導致GPU里存在大量的冗余紋理。
解決方案:
1.實現(xiàn)紋理的LRU緩存于置,淘汰的紋理保存到沙盒里茧吊,使用時再恢復到GPU。
2.加載紋理盡量復用八毯,如texImage2D的最后一個參數(shù)是image或Canvas搓侄,會直接復用紋理。
小游戲死鎖卡住
原因:JS core 的JSContext會在創(chuàng)建它的線程創(chuàng)建JS虛擬機话速,虛擬機會在這個現(xiàn)場添加自己的JS runloop讶踪。在需要在其他線程移步執(zhí)行此JSContext中的JS代碼時,會有一定概率死鎖泊交。
解決方案:
JSContext的創(chuàng)建乳讥、執(zhí)行代碼全部都放在一個線程完成。
渲染過程Crash廓俭,掛在紋理GL命令
原因:我們的開放數(shù)據(jù)域和主域是分別獨立的線程云石,但JS的sharedCanvas在兩個域都可以訪問,導致它在底層的不同OpenGL context之間產(chǎn)生競爭研乒,導致偶先的Crash汹忠。
解決方案:
在上層做邏輯保護,加GPU鎖告嘲,避免同一份GPU資源在不同OpenGL context中產(chǎn)生競爭問題错维。