Windows Phone中的圖形渲染處理

  • 前言

   這篇文章主要介紹Windows Phone中XAML的渲染處理過程,你能夠根據下文中所提到的內容來優化現有的XAML頁面,來提升頁面渲染的性能。緩存

     XAML的渲染包括如下兩個階段:app

     1. 光柵化(Rasterization) 光柵化是將圖形的表現形式從以基於矢量(vector-based)的圖形(好比:線、文字和矩形)轉換成基於像素(pixel-based)的圖形,從而能夠使圖像直接顯示在屏幕上的處理過程。這個轉換過程要先在內存中先爲位圖分配一個緩衝區,而後將以矢量圖形一個像素一個像素的轉換成位圖,並完成蒙板和梯度值的計算。這個光柵化的過程徹底是由CPU來處理的。ide

      2. 組合(Composition) 在每個UIElement都被光柵化以後渲染器按照原始元素Z軸的順序講各個緩衝區上的位圖層疊到彼此之上。這個處理將各個位圖組合到了一塊兒,因此渲染器要負責處理元素的透明度和任何轉換(如:大小和位置),最終將位圖展現在設備的屏幕上。組合處理CPU或者GPU來完成。性能

      下面這張圖經過將兩個UI Element展現在屏幕上,說明了光柵化和組合階段的過程,其中一個具備不透明蒙板。優化

      渲染的過程是很是複雜的,由於屏幕上的圖形都是由UI Element的集合組合在一塊兒的,而不少UI Element又是由其餘UI Element組合的。在內部,XAML使用一種全部元素均可見和渲染的層次結構的視覺樹(visual tree)。好比要呈現一個普通的屏幕圖形, XAML經過光柵化及組合可視化樹中的元素,以減小必須分配的內存緩衝區的數量。這個處理過程將盡量的將元素覆蓋到現有的緩衝區中。開發人員能夠經過緩衝組合,以指定特定的UI元素如何被分組和由GPU組成。適當的緩存能夠顯着提升用戶界面的幀速率。動畫

     若是UI Element是可動的,它將浪費一些處理器的時間,直到動畫結束才進行光柵化處理。此外,即便元素只移動了其中一小部分,也須要對整個UI Element進行從新組合。爲了優化渲染過程,XAML自動推遲了某些元素的組合過程,從而是元素的組合步驟能夠迅速的經過GPU來完成。使用GPU來加速渲染過程一般被稱爲硬件加速。若是您的設備沒有GPU或因其餘緣由不能硬體加速,XAML採用圖形設備接口(GDI )以較低的渲染速度來經過Z軸的順序一像素一像素繪製UI。this

  • 渲染處理過程當中的線程

     在XAML中有兩個主要的線程:UI線程和Compositor線程。爲了建立響應及時的應用,瞭解這兩個線程是很是重要的。
spa

     1. UI Thread線程

     UI線程負責如下任務:
3d

  • 用戶輸入的處理。
  • XAML對象的建立和解析。
  • 首次繪製全部視圖到屏幕上。
  • 執行每幀回調或其餘用戶代碼。

     爲了使您的應用程序儘量靈活響應,必須儘可能保持UI線程的輕量和空閒。

     2. Compositor Thread

     組合線程是一個超輕量級的線程,它爲GPU簡單的組合元素的紋理,它處理GPU上的被定義爲Storyboards類型或者基礎紋理的繪製類型的動畫。這些動畫類型包括:

  • Translation. 改變對象的位置。
  • Scaling. 放大或縮小對象以產生深度的視覺。
  • Rotation. 旋轉對象。
  • Draws. 屏幕首次呈現全部視圖。
  • Plane Projection. 經過映射到二位平面來展現對象的3D變化。

     注意,任何使用了不透明蒙板,非矩形剪切或者大小改變的動畫的對象大於2,048 x 2,048像素,它們將在UI線程上光柵化。

  • 渲染處理過程的例子

     爲了說明前面的概念,請參閱以下圖所示的界面。屏幕上的地球圖像製做成動畫繞着屏幕剩餘邊界雖然這個屏幕顯示了一個很是簡單的用戶界面它包括全部上面列出的關鍵構建模塊來講明渲染過程.

 

     這個圖像是由下面這個XAML用戶控件構成的。

<UserControl
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   x:Class="HelloWorld.MainPage"
   Width="300" Height="200">

   <Grid x:Name="LayoutRoot">
      <Grid x:Name="_Background" Background="{StaticResource BlueWashBrush}">
         <Image x:Name="_LightHexes" Source="Assets/Hexes.png" Stretch="Fill"/>
         <Image x:Name="_DarkHexes" Source="Assets/BlackHexes.png" Stretch="Fill">
            <Image.OpacityMask>
               <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                  <GradientStop Offset="0"/>
                  <GradientStop Color="#C0FFFFFF" Offset="0.6"/>
               </LinearGradientBrush>
            </Image.OpacityMask>
         </Image>
      </Grid>
      <Rectangle x:Name="_Border" Fill="#FF969696" Stroke="White" Margin="0,10,90,10" RadiusX="10" RadiusY="10" 
         HorizontalAlignment="Center" Width="180" Opacity="0.5"/>
      <TextBlock x:Name="_Label" HorizontalAlignment="Center" Margin="0,0,90,15" VerticalAlignment="Bottom" 
         FontFamily="Verdana" FontSize="21.333" Text="Hello World" TextWrapping="Wrap" FontWeight="Bold"/>
      <Button x:Name="_Button" HorizontalAlignment="Right" Margin="0,0,8,8" VerticalAlignment="Bottom" Width="75" 
         Content="Close" FontFamily="Verdana" FontSize="16"/>
      <Image x:Name="_Globe" Height="138" HorizontalAlignment="Center" Margin="0,20,90,0" VerticalAlignment="Top" 
         Width="138" Source="Assets/Globe138x138.png" Stretch="Fill" RenderTransformOrigin="0.5,0.5" 
         CacheMode="BitmapCache">
         <Image.RenderTransform>
            <TransformGroup> 
                 <ScaleTransform/>
                 <SkewTransform/>
                 <RotateTransform/>
                 <TranslateTransform/> 
            </TransformGroup>
         </Image.RenderTransform>
      </Image>
   </Grid>
</UserControl>
View Code

     下圖展現了上面代碼的樹形結構。

     XAML的渲染過程執行如下步驟來呈現上圖所示的可視化樹:

  • 分配給LayoutRoot的主緩衝區。
  • 光柵化漸變畫筆的_Background網格到主緩衝區。
  • 光柵化_LightHexes到一個臨時緩衝區和撰寫主緩衝區。
  • 光柵化_DarkHexes到一個臨時緩衝區和撰寫主緩衝區。
  • 光柵化_Border矩形到一個臨時緩衝區和撰寫主緩衝區。
  • 光柵化文字_Label到一個臨時緩衝區,並綴以主緩衝區。
  • 分配給_button一個臨時的緩衝區,而後光柵化並撰寫全部的按鈕元素(按鈕的模板中)到這個臨時緩衝區中。
  • 構圖_button緩衝區與主緩衝區。
  • 構成_Globe與主緩衝區。

     注意,在渲染器執行的過程當中遵循如下規則:

  1. 只分配必要的緩衝區。若是有可能覆蓋一個元素到一個現有的緩衝區中,將不分配新的緩衝區。
  2. 它使用的CPU來執行全部光柵化和組合操做。若是該設備有GPU和啓用硬件加速,這個過程GPU上完成。

      在動畫過程當中,只有_Globe元素在畫面上移動,沒有其餘任何元素的變化。XAML沒有必要逐幀來執行全部光柵化和組合的步驟。最優行爲是保存已經完成的每幀動畫步驟的結果,經過保存的步驟來組合_Globe。 在前面的代碼塊22行提到CacheMode屬性來明確地告訴渲染器單獨對待_Globe元素,以產生緩存的效果。

      在XAML中緩存是自動的,不必再設置CacheMode屬性。注意,分離緩存的對象和元素分組是緩存和提升動畫速度成功的關鍵。

相關文章
相關標籤/搜索