2012-07-11 63 views
2

我們的產品包含一種軟件圖像解碼器,它基本上可以生成需要快速複製屏幕(我們在iOS上運行)的全幀像素數據。將RGB像素數據高效複製到iOS屏幕上

目前我們使用的是CGBitmapContextCreate,我們直接訪問內存緩衝區,然後對每一幀調用CGBitmapContextCreateImage,然後將該位圖繪製到屏幕上。這對於在iPad的視網膜顯示器上進行全屏刷新的速度太慢了,但是對於非視網膜設備來說,這還是可以的。我們嘗試了各種基於OpenGL ES的方法,包括使用glTexImage2D和glTexSubImage2D(本質上是渲染紋理),但CPU使用率仍然很高,我們無法獲得超過30 FPS的在iPad 3上進行全屏刷新。問題在於,使用30 FPS時,僅將像素複製到屏幕上時,CPU使用率接近於100%,這意味着我們沒有太多工作來處理我們自己的渲染。中央處理器。

我們願意使用OpenGL或任何iOS API來提供最佳性能。像素數據格式化爲每像素32位RGBA數據,但我們在這裏有一些靈活性...

有什麼建議嗎?

+0

您是否使用儀器來查看所有CPU的操作?我做了類似的事情,發現花了很多時間將RGBA轉換爲ARGB(並不是說這是你的問題,但如果你還沒有做到這一點,它可能有助於看到一個配置文件) – nielsbot 2012-07-11 00:27:59

+0

「到底畫什麼」屏幕「是什麼意思?你是在繪製一個UIView的'-drawRect:'方法,還是將CGImage放在一個圖層中,或者使用UIImageView?後兩種方法應該明顯更快 - 請參閱此[以前的答案](http://stackoverflow.com/questions/10410106/drawing-image-with-coregraphics-on-retina-ipad-is-slow/10424635#10424635 )。 – 2012-07-11 02:45:25

+0

你的「glTexSubImage2D」方法是什麼?我相信如果做得正確,這應該足夠快。我如何理解你在做什麼是你在CPU上處理原始像素數據並將這些數據推送到GPU並渲染它們。這是最大的約4kx4kx4B(64MB)的數據被推到一個完整的紋理(對於iPad3),似乎並不太多..無論如何,如果在任何情況下,這是什麼原因導致fps的下降,我沒有看到任何更好的方式,然後直接在像素的GPU上工作。 – 2012-07-11 08:30:30

回答

0

然後可以將pbuffer或FBO用作由OpenGL ES進一步呈現的紋理貼圖。這被稱爲渲染到紋理或RTT。它在EGL中的搜索緩衝區或FBO更快搜索

+0

Render to Texture如何解決這個問題?我們希望從CPU中取出現有的位並將它們傳送到屏幕上。我們的渲染是由CPU完成的,而不是由GPU完成的。 – ldoogy 2012-07-11 04:31:51

+0

根據我的說,UIImage是最快速的從CPU訪問IOS – 2012-07-11 08:23:15

+0

@talktomevintron - 不,它絕對不是。在我的基準測試中,從UIImage中提取原始像素數據時有很大的核心圖形開銷。用其他格式的原始像素數據處理會更好。 – 2012-07-13 19:33:02

2

所以,壞消息是你遇到了一個非常困難的問題。我已經在這個特定的領域做了大量的研究,目前唯一的方法就是使用h.264解碼器來實現將全屏大小爲2x的幀緩衝區。一旦圖像數據已經解碼成實際的內存(看一下GPUImage),就可以用OpenGL完成一些不錯的技巧。但是,最大的問題不在於如何將像素從實時內存移動到屏幕上。真正的問題是如何將像素從磁盤上的編碼形式移動到實時內存中。可以使用文件映射內存來保存磁盤上的像素,但是IO子系統速度不夠快,無法將足夠的頁面交換出來,以便能夠從映射內存中傳輸2個全屏大小的圖像。這個功能在1x全屏大小的情況下效果很好,但現在2倍大小的屏幕實際上是內存量的4倍,硬件無法跟上。您也可以嘗試以更加壓縮的格式將幀存儲在磁盤上,例如PNG。但是,然後解碼壓縮格式會將問題從IO綁定到CPU綁定,並且您仍然卡住。請查看我的博客文章opengl_write_texture_cache,瞭解我在該方法中找到的完整源代碼和時序結果。如果你有一個非常具體的格式,你可以限制輸入圖像數據(比如8位表格),那麼你可以使用GPU通過着色器將8位數據作爲32BPP像素進行傳輸,如下例所示:xcode project opengl_color_cycle 。但是,我的建議是考慮如何使用h.264解碼器,因爲它實際上能夠解碼硬件中的大量數據,並且沒有其他方法可能會爲您提供所需的結果。

0

經過幾年以及我遇到這種需求的幾種不同情況,我決定爲iOS實現一個基本的「pixel viewer」視圖。它支持高度優化的各種格式的像素緩衝區顯示,包括32-bpp RGBA,24-bpp RGB和幾種YpCbCr格式。

它還支持所有UIViewContentMode *的用於智能的縮放,縮放,以適應/填充等

該代碼是高度優化的(使用OpenGL),並在更老iOS設備如iPhone實現優良的性能5或原裝iPad Air。在這些設備上,除了24bpp格式之外,所有像素格式都達到60fps,達到30-50fps(我通常通過在設備原始分辨率下顯示像素緩衝區來進行基準測試,所以顯然iPad必須推出比iPhone更多的像素5)。

請檢查出EEPixelViewer

1

CoreVideo很可能是您應該查看的框架。藉助OpenGL和CoreGraphics方法,您將受到將主存儲器中的位圖數據移動到GPU內存上的成本的困擾。這筆費用也存在桌面上,但在iPhone上尤其痛苦。

在這種情況下,OpenGL不會爲CoreGraphics提高速度,因爲瓶頸是紋理數據副本。 OpenGL將爲您提供更高效的渲染管道,但損壞將由紋理副本完成。

所以CoreVideo是要走的路。就我所瞭解的框架而言,它解決了您遇到的問題。