圖片渲染流程初探

  • CPU與GPU

    • CPU緩存

      中央處理器(CPU),是電子計算機的主要設備之一,電腦中的核心配件。其功能主要是解釋計算機指令以及處理計算機軟件中的數據。CPU是計算機中負責讀取指令,對指令譯碼並執行指令的核心部件。中央處理器主要包括兩個部分,即控制器、運算器,其中還包括高速緩衝存儲器及實現它們之間聯繫的數據、控制的總線。電子計算機三大核心部件就是CPU、內部存儲器、輸入/輸出設備。中央處理器的功效主要爲處理指令、執行操做、控制時間、處理數據markdown

    • GPU併發

      圖形處理器(英語:Graphics Processing Unit,縮寫:GPU),又稱顯示核心、視覺處理器、顯示芯片,是一種專門在我的電腦、工做站、遊戲機和一些移動設備(如平板電腦、智能手機等)上作圖像和圖形相關運算工做的微處理器oop

    • 圖片渲染過程當中分別做了什麼工做
      CPU:佈局

      1. 確認場景中哪些對象須要被渲染,一個object只要在符合特定的規則纔會被渲染。例如,當處於相機的視錐體內的對象能夠被渲染,而超出(不在視錐體內)的部分則被剔除(Culled),不進行渲染
      2. CPU會收集這些將要被渲染的每個對象的數據,而且整合成指令,即咱們常說的Draw Calls。一個Draw Call包含一個單獨的網格(mesh)數據和它將如何進行渲染的信息。好比,須要對材質使用哪些貼圖等。在某些狀況下,使用相同的設置的object數據會被合併進一個Draw Call。將不一樣的object數據合併到一個Draw Call的行爲咱們稱之爲 合批(Batching)。
      3. CPU會爲每個Draw Call建立一個數據包叫作 batch,然而,batch中包含的數據不只僅是draw call,還有一些數據因爲與咱們探討的渲染性能問題無關,所以就不在這裏展開。一旦完成了batch工做,CPU接着會進行以下工做:
      4. 發送一條指令給到GPU變動渲染狀態(Render State)。這個指令咱們稱爲 SetPass Call。SetPass Call的做用是告訴GPU在渲染下一個材質的時候該使用哪種設置。SetPass Call僅當從前一個材質到下一個材質確實須要變動渲染狀態的狀況下CPU纔會發出
      5. CPU發送一條Draw Call指令給到GPU。Draw Call指示GPU按照SetPass Call定義的設置來對具體的材質進行渲染。
      6. 某種狀況下,你的batch可能包含不止一個渲染通道(pass),這取決於你的 shader 代碼中pass的代碼塊,一個pass代碼塊就須要GPU變動一次渲染狀態。因此,一個batch中每多包含一個pass,CPU就要新發送一次SetPass Call到GPU,而後再把Draw Call發送一次到GPU。

      與此同時, GPU 會進行以下工做:性能

      1. GPU按照CPU的要求完成渲染任務。
      2. 若是當前任務是一個SetPass Call,那麼GPU會變動當前的渲染狀態(Render State)。
      3. 若是當前任務是一個Draw Call, GPU就渲染指定的材質。經過頂點着色器、片元着色器進行渲染

      總結一下
      CPU就是計算出須要渲染的模型數據,而後發送指令調用GPU去渲染。 首先讀取繪製模型,CPU將讀取到的多邊形轉交給GPU,GPU根據模型數據繪製出對應的模型骨架,注意這一步沒有紋理只有線框。GPU將模型數據放進顯存,GPU同時也爲模型貼材質,給模型上顏色。CPU相應從顯存中獲取多邊形的信息。而後CPU計算光照後產生的影子的輪廓。等CPU計算出後,顯卡的工做又有了,那就是爲影子中填充深的顏色。不管多牛的顯卡,光影都是CPU計算的,GPU只有2個工做,1多邊形生成。2爲多邊形上顏色。 spa

  • 計算機渲染原理

    • 掃描方式
      • 隨機掃描
        比較老的掃描方式了,採用隨機定位的方式控制電子束的運行(缺點不能顯示太複雜的圖像)
      • 光柵掃描
        衝上到下依次掃描
    • 光柵掃描顯示系統結構
      • 最簡單的光柵圖形系統結構
      • 經常使用的光柵圖形系統結構
      • 高級光柵圖形系統結構
  • 屏幕撕裂與卡頓狀況

    • 屏幕撕裂
      圖片渲染流程:
      GPU進⾏渲染->幀緩存區⾥ ->視頻控制器->讀取幀緩存區信息(位圖) -> 數模轉化(數字信號處->模 擬型號) ->(逐⾏掃描)顯示
      衝上面的流程能夠看出基本上分紅兩個階段:
      1. GPU將處理後的數據(位圖)存放到幀緩衝區中
      2. 視頻控制器衝幀緩衝區中拿到數據進行轉化掃描顯示
        因此若是第一步過快第二步太慢就會形成撕裂現象。
        總結一下:首先GPU將數據處理完成後存到幀緩衝區,完美的處理結果是視頻控制器恰好顯示完幀緩衝區中的數據的時候立馬下一幀的數據更新到了幀緩衝區中,可是呢視頻控制器處理速度有點慢,可是GPU處理又很快就會出現第一幀尚未渲染完成的時候第三幀的數據已經處理完成此時第三幀的數據就會將幀緩衝區中第二幀的數據替換掉這就形成了第二幀丟失第一幀完成後直接衝第三幀開始渲染,這就形成了撕裂現象
    • 卡頓狀況
      針對撕裂的狀況,蘋果垂直同步Vsync + 雙緩存區 DoubleBuffering,垂直同步意思就是給幀緩衝區上把鎖,放到幀緩衝區中將該緩衝區上鎖,等視頻控制器拿到幀緩衝區中的數據,並掃描顯示完成的時候在解鎖,這樣就解決了撕裂問題,可是問題又來了,通常呢渲染一幀的時間是16ms,超過16ms則會渲染下一幀,可是呢CPU/GPU處理數據的速度要大於16ms,這就形成在渲染下一幀的時候幀緩衝區中沒有數據,此時就還會顯示當前一幀(其實不加垂直信號也有可能出現掉幀的狀況,可是狀況要比加垂直同步的好得多,應爲gpu處理完數據不會等待直接覆蓋幀緩衝區中的內容,這樣就保證了渲染過程當中CPU/GPU一直在工做,二添加垂直同步以後就有可能會出現CPU/GPU等待的狀況,因此就加大了掉幀的概率),爲了更好的解決這個問題又引入了三緩衝區,其實就是更大化的利用GPU/CPU而已並不能衝根本上解決問題。
      總結一下:掉幀不是一幀沒了而是存在等待狀況,其實就是CPU/GPU處理數據的速度跟不上渲染的速度,目前爲止尚未可以徹底解決掉幀的問題
  • iOS下的渲染流程

    1. 顯示邏輯:
      • CoreAnimation提交會話,包括本身和子樹(view hierarchy)的layout狀態等;
      • RenderServer解析提交的子樹狀態,生成繪製指令
      • GPU執行繪製指令
      • 顯示渲染後的數據
    2. 提交多級
      • 佈局(Layout)
        • 調用layoutSubviews方法
        • 調用addSubview:方法
      • 顯示(Display)
        • 經過drawRect繪製視圖;
        • 繪製string(字符串);
      • 準備提交
        • 解碼圖片;
        • 圖片格式轉換;
      • 提交
        • 打包layers併發送到渲染server;
        • 遞歸提交子樹的layers;
        • 若是子樹太複雜,會消耗很大,對性能形成影響;

    總結一下:
    HandleEvents : 事件處理
    Commit Transaction: 圖⽚
    Render Server :解碼(CPU) -> CoreAnimation -> 提交OpenGL -> GPU ->渲染流程(頂點數據->頂點着⾊器->⽚元着⾊器-> runloop ->顯示)
    code

相關文章
相關標籤/搜索