圖片展示到屏幕的流程
讓我們來(lái)看下一張圖片展示的全過(guò)程:


1)讀入U(xiǎn)IImage
在代碼中,我們讀取圖片一般需要一個(gè)path,無(wú)論是本地圖片還是遠(yuǎn)程圖片,我們獲取到的實(shí)際上是一個(gè)二進(jìn)制數(shù)據(jù)串,用UIImage來(lái)表示。
- 用UIImage為UIImageView賦值
3)系統(tǒng)偵測(cè)數(shù)據(jù)變化
一個(gè)系統(tǒng)提供的隱式事務(wù)CATransaction捕獲了UIImageView圖層樹(shù)的變化。在下一個(gè)runloop到來(lái)時(shí),Core Animation提交了這個(gè)CATransaction,開(kāi)始準(zhǔn)備渲染所需的位圖BitMap數(shù)據(jù)。
4)解壓縮UIImage數(shù)據(jù)到位圖BitMap
位圖實(shí)際上是個(gè)像素?cái)?shù)組,對(duì)應(yīng)著圖片上的每一個(gè)點(diǎn)。如果提供bmp文件,確實(shí)不需要解壓縮,但是平常使用最為廣泛的png或jpg圖片都是壓縮后的位圖。需要對(duì)齊進(jìn)行解壓縮。
- GPU進(jìn)行坐標(biāo)變換
一張1000*1000的BitMap,我們可以對(duì)其變形渲染到任意尺寸的UIImageView上,GPU需要對(duì)坐標(biāo)進(jìn)行轉(zhuǎn)換,計(jì)算出實(shí)際的屏幕坐標(biāo)。
6)頂點(diǎn)著色器
它把一個(gè)單獨(dú)的頂點(diǎn)作為輸入。頂點(diǎn)著色器主要的目的是把3D坐標(biāo)轉(zhuǎn)為另一種3D坐標(biāo)(后面會(huì)解釋),同時(shí)頂點(diǎn)著色器允許我們對(duì)頂點(diǎn)屬性進(jìn)行一些基本處理。
7)圖元裝配階段
將頂點(diǎn)著色器輸出的所有頂點(diǎn)作為輸入(如果是GL_POINTS,那么就是一個(gè)頂點(diǎn)),并所有的點(diǎn)裝配成指定圖元的形狀;
8)幾何著色器
圖元裝配階段的輸出會(huì)傳遞給幾何著色器(Geometry Shader)。幾何著色器把圖元形式的一系列頂點(diǎn)的集合作為輸入,它可以通過(guò)產(chǎn)生新頂點(diǎn)構(gòu)造出新的(或是其它的)圖元來(lái)生成其他形狀。
9)光柵化階段
幾何著色器的輸出會(huì)被傳入光柵化階段(Rasterization Stage),這里它會(huì)把圖元映射為最終屏幕上相應(yīng)的像素,生成供片段著色器(Fragment Shader)使用的片段(Fragment)。在片段著色器運(yùn)行之前會(huì)執(zhí)行裁切(Clipping)。裁切會(huì)丟棄超出你的視圖以外的所有像素,用來(lái)提升執(zhí)行效率。
10)片段著色器
片段著色器的主要目的是計(jì)算一個(gè)像素的最終顏色,這也是所有OpenGL高級(jí)效果產(chǎn)生的地方。通常,片段著色器包含3D場(chǎng)景的數(shù)據(jù)(比如光照、陰影、光的顏色等等),這些數(shù)據(jù)可以被用來(lái)計(jì)算最終像素的顏色。
11)測(cè)試與混合
在所有對(duì)應(yīng)顏色值確定以后,最終的對(duì)象將會(huì)被傳到最后一個(gè)階段,我們叫做Alpha測(cè)試和混合(Blending)階段。這個(gè)階段檢測(cè)片段的對(duì)應(yīng)的深度(和模板(Stencil))值(后面會(huì)講),用它們來(lái)判斷這個(gè)像素是其它物體的前面還是后面,決定是否應(yīng)該丟棄。這個(gè)階段也會(huì)檢查alpha值(alpha值定義了一個(gè)物體的透明度)并對(duì)物體進(jìn)行混合(Blend)。所以,即使在片段著色器中計(jì)算出來(lái)了一個(gè)像素輸出的顏色,在渲染多個(gè)三角形的時(shí)候最后的像素顏色也可能完全不同。