2012-05-29 157 views
4

在iOS上,我能創造3個CGImage對象,並使用CADisplayLink在60fps做在iOS上,CALayer位圖(CGImage對象)如何顯示在圖形卡上?

self.view.layer.contents = (__bridge id) imageArray[counter++ % 3]; 

ViewController內,每一次,圖像設置爲視圖的CALayer的contents,這是一個位圖。

而這一切都可以改變屏幕顯示的內容。屏幕將以60fps循環播放這3張圖片。沒有UIView的drawRect,沒有CALayer的display,drawInContext或CALayer的代表的drawLayerInContext。它所做的只是更改CALayer的contents

我也試過在self.view.layer上添加一個較小尺寸的子圖層,並設置該子圖層的contents。這個子圖層將循環顯示這3幅圖像。

所以這和以前甚至在Apple上都很相似](或者甚至在King's Quest III時代,這是DOS視頻遊戲,其中有1個位圖,屏幕只是不斷顯示位圖是什麼。

除了這個時候,它不是1位圖,而是一個樹或一個鏈接的位圖列表,並且顯卡不斷使用畫家模型將這些位圖(位置和不透明度)繪製到主屏幕上。因此,似乎drawRect,CALayer,一切,都旨在實現這個最終目的。

它是如何工作的?顯卡是否需要一個有序的位圖列表或位圖樹? (然後不斷顯示它們,爲了簡化,我們沒有考慮CA框架中的隱式動畫)圖形卡處理層實際發生了什麼? (實際上,這種方法在iOS,Mac OS X和PC上幾乎相同?)

(這個問題旨在瞭解我們的圖形編程實際上是如何在現代圖形卡中呈現的,例如,if我們需要了解UIView和CALayer的工作原理,或者直接使用CALayer的位圖,但我們需要了解圖形體系結構。)

回答

4

現代顯示庫(如iOS和Mac OS中使用的Quartz)使用硬件加速合成。這些工作與OpenGL等計算機圖形庫如何工作非常相似。實質上,每個CALayer都被保存在一個單獨的表面中,這個表面被視頻硬件緩衝和渲染,就像3D遊戲中的紋理一樣。這在iOS中非常好地實現,這就是爲什麼iPhone以流暢的用戶界面而着稱的原因。在「過去的日子」(即Windows 9x,Mac OS Classic等)中,屏幕基本上是一個大的幀緩衝區,並且通過例如圖像顯示的所有東西都被顯示。移動窗口必須由每個應用程序手動重新繪製。重繪主要由CPU完成,這對動畫性能提出了上限。由於涉及重新繪製,動畫通常非常「閃爍」。這種技術主要適用於沒有太多動畫的桌面應用程序。值得注意的是,Android使用(或至少以前使用過)這種技術,這是將iOS應用程序移植到Android時的一大問題。

舊時代的遊戲(例如DOS,街機等,在Mac OS classic上也有很多使用),被稱爲sprite animation的東西被用來提高性能,並通過將運動圖像保存在屏幕外的緩衝區來減少閃爍由硬件渲染並與顯示器的vblank同步,這意味着即使在非常低端的系統上,動畫也很流暢。但是,這些圖像的尺寸非常有限,屏幕分辨率很低,只有今天iPhone屏幕的10-15%左右。

2

您在這裏有一個合理的直覺,但在contents和顯示之間仍然有幾個步驟。首先,contents不一定是CGImage。它通常是一個叫做CABackingStorage的私人課程,它不完全相同。在很多情況下,硬件優化會繞過將圖像渲染到主內存中,然後將其複製到視頻內存。而且由於各層的contents都是合成在一起的,所以你仍然是來自「真實」顯示存儲器的一種方式。更不用說對contents的修改只是直接影響模型層,而不是表現層​​或渲染層。另外還有可以將圖像直接存儲在視頻內存中的對象。有很多不同的東西在發生。

所以答案是,不,視頻「卡」(芯片;它是PowerVR BTW)不採用有序的一堆圖層。它以較低的數據記錄方式記錄。有些東西(特別是Core Animation的一部分,也許是CGLayer)似乎是OpenGL紋理的包裝,但其他一些可能是Core Graphics直接訪問硬件本身。一旦達到堆棧的這個級別,它就全部是私有的,並且可以從版本到版本以及設備之間進行更改。

您也可以找到布拉德·拉爾森的響應這裏很有用: iOS: is Core Graphics implemented on top of OpenGL?

您還可能有興趣在iOS:PTL第6章。儘管沒有涉及實現細節,但它包含了很多關於如何提高繪圖性能和最佳利用Core Graphics硬件的實際討論。第7章詳細介紹了CALayer繪圖中涉及的所有開發人員可訪問的步驟。

相關問題