請教各位在pc上使用webgl以及opengl渲染yuv數據的性能問題,有何改進方向?

背景:

在pc機器上,視頻數據解碼成yuv以後,把yuv數據以紋理方式通過webgl渲染canvas上或者opengl渲染windows窗口上,最後測試發現,opengl渲染效率比webgl渲染效率高很多;在性能比較差的機器上,整體cpu差異特別明顯;想請教各位,webgl的渲染上,有什麼改進的方向?謝謝。

感謝大家的回復;

把問題澄清一下:JS中不考慮視頻解碼等耗時問題,只考慮webgl的性能問題;

為了驗證chrome webgl的性能,又做了一個實驗,讓IE 11與chrome運行同樣的代碼,把yuv數據作為紋理的代碼去掉,僅僅只是繪製顏色塊(5個canvas,其中2個canvas 30fps繪製,3個canvas 15fps繪製),最後發現在較差機器A上運行時,ie的性能比chrome的性能高出50%,當然在性能較好的機器上,差距沒有這麼大;大家如果方便,可以幫助測試一下,看看效果;(https://yunpan.cn/cvxq6UTdLqUNb,提取碼:f534)

性能的差距促使我分析一下webgl相關實現:

windows opengl實現:

所有的api函數包含在OpenGL32.DLL中,如果顯卡支持硬體加速,那麼就調用顯卡驅動支持的opengl能力,否則使用OpenGL32.dll中軟體實現能力;在測試機A上intel的集成顯卡,因此使用的是集成顯卡中的opengl能力;

windows chrome實現:

通過分析webgl的所有介面調用是先調用到libGLESv2.dll中的介面,然後調用D3D的介面實現;通過官網查找,webgl實現是調用在ANGLE項目模擬的OpenGL ES的介面,然後再調用D3D介面;

windows ie 11實現:

在webgl中直接調用D3D介面,可能中間也有薄薄的一層介面封裝;

問題總結:

chrome的cpu高是否由於在中間加了一層OpenGL ES的實現導致的呢?如果是這樣,為什麼還要使用ANGLE項目,而不直接使用OpenGL32.dll的介面,這樣也能解決跨平台的問題?


你可以把這個問題甩在整天叫囂js性能不比原生差多少的人的臉上,讓他們解決。


如果 YUV 數據來自視頻流,JS 的做法是:用一個隱藏的 Video 元素播放視頻,Video 元素像 Image 一樣直接傳遞進 gl.texImage2D,然後紋理的內容就是視頻了。具體可以參考這裡:Animating textures in WebGL

如果 YUV 是壓縮過的需要用 JS 先解壓,那就沒有辦法了。JS 的效率平均也就 C 的 1/10 吧。如果有 SIMD.js 可能稍微好點。

如果 YUV 不需要解碼,那麼用 shader 做 YUV 覆蓋會比較快。update 的時候一定要用 requestAnimationFrame 會影響 GPU CPU 同步效率。


因為windows對opengl的支持不友好,D3D是效果最好的api,所以才會用opengl轉D3D這種中轉,這是chrome的考量,對IE的實現不清楚,估計是依樣畫葫蘆吧。

你是用shader轉換的,瀏覽器底層會先把你的glsl編譯為hlsl,產生的hlsl不一定會有優化。

瀏覽器是由多個圖層組成的,渲染不同圖層不一定都採用硬體,結果需要進行合成,這裡又有性能損耗。

webgl的渲染在chrome里屬於離屏渲染。

圖像數據從JS數組中傳遞到顯存,之前,需要轉換成裸數據。

再有就是chrome,GPU渲染跟網頁渲染是在不同的進程,通訊之間又有性能的損耗。

cpu佔用高,這個我感覺應該是從JS數據結構轉換為能為shader獲取的數據時產生的,這裡面應該有大量的複製操作。

對於桌面的opengl,是通過句柄直接渲染到屏幕的,再有使用到的shader,就是你寫的shader,c++或c的數組數據,直接就能把地址傳遞給顯卡驅動,不需要進行數據結構的轉換,複製。所以性能當然差距很大了。

所以,語言的性能並不是其瓶頸。

對IE的不了解。


推薦閱讀:

震驚!時間之神又給了這個古老的API+了0.1
如何實現魚眼效果?
在 OpenGL 中應用查找表(LUT)技術時,如何避免紋理數據自動歸一化導致的圖像異常?
不同GLSL版本之間的區別?
OpenGL ES2 對象樹繪製與 VBO組織問題?

TAG:HTML5 | OpenGL | WebGL | Canvas |