Android HWUI

青山牧云人發表於2024-08-14

Android HWUI(Hardware Accelerated Rendering Engine for UI)是Android系統中用於處理UI渲染的硬體加速引擎。它的主要作用是利用GPU(圖形處理單元)來加速UI的渲染過程,從而提高渲染效率和流暢度。以下是Android HWUI工作的主要方式和步驟:

一、基本工作原理

傳統軟體的UI繪製是依靠CPU來完成的,硬體加速就是將繪製任務交由GPU來執行。

HWUI基於GPU加速,透過Skia Backend與GPU進行互動,將UI繪製任務從CPU轉移到GPU上執行。這種方式可以顯著提高繪製效能,特別是在高解析度螢幕和複雜UI場景下。

  • GPU相比CPU更加適合完成光柵化、動畫變換等耗時任務,在移動裝置上比起使用CPU來完成這些任務,GPU會更加省電,帶來的使用者體驗也會更佳。
  • 現代移動GPU支援可程式設計管線,可以高效地開發應用介面的一些特效(吸入、漸變、模糊、陰影)


Skia Backend有兩種:SkiaGl和SkiaVk,分別對應後端OpenGLES和Vulkan

二、核心元件

  1. Skia圖形庫:
    • Skia是HWUI的核心圖形庫,提供了基礎的繪製功能,如圖形、文字、點陣圖等。
    • 它支援硬體加速渲染,能夠充分利用GPU進行併發計算,加快UI介面的渲染速度。
    • 程式碼示例
      // 建立畫布
      Canvas canvas = new Canvas(bitmap);
      // 繪製矩形
      Paint paint = new Paint();
      final int color = Color.BLUE;
      paint.setColor(color);
      RectF rect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());
      canvas.drawRoundRect(rect, 32, 32, paint);
  2. OpenGL ES/Vulkan:
    • OpenGL ES/Vulkan是HWUI與GPU之間的橋樑,負責將Skia生成的繪製命令轉化為GPU能夠執行的指令序列。
    • OpenGL ES 3.0是HWUI的預設版本,具有更好的功能和效能表現。未來HWUI的Backend預設會切換到Vulkan。
  3. DisplayList:
    • DisplayList是HWUI的渲染列表,用於記錄繪製操作以及它們的位置、大小等資訊。
    • 這些操作被顯式地快取起來,以便後續可以更快速地進行處理,並允許檢視樹中相同的部分在多個幀之間重複使用,從而節約記憶體和頻寬。
    • 程式碼示例
      // 建立DisplayList
      DisplayList displayList = new DisplayList("MyList");
      displayList.start(512, 512); //設定寬高
      // 新增繪製操作
      Paint paint = new Paint();
      paint.setColor(Color.RED);
      paint.setStyle(Paint.Style.FILL);
      displayList.drawRect(64, 64, 256, 256, paint);
      // 結束DisplayList
      displayList.end();
  4. RenderNode:
    • RenderNode是HWUI的渲染節點,對應於檢視層次結構中的一個節點。
    • 每個View持有一個RenderNode,這些RenderNode組成樹形結構,用於管理和組織渲染任務。
    • RenderNode負責儲存和管理View繪製過程中使用的各種屬性,如透明度和邊框等。
    • 程式碼示例
      // 建立RenderNode
      RenderNode renderNode = new RenderNode("MyNode");
      // 更新RenderNode屬性
      View view = findViewById(R.id.myView);
      renderNode.setPosition(view.getLeft(), view.getTop());
      renderNode.setElevation(view.getElevation());
      Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
      renderNode.setBitmapCache(bitmap);
      // 新增子節點
      RenderNode child = new RenderNode("MyChild");
      //更新child屬性
      renderNode.addChild(child);
  5. Layers
    • Layer是HWUI的另一個重要概念,用於實現UI的專業效果和動畫效果。
    • 在Android 10及以前的系統中,所有檢視都隸屬於共享的系統組層級。但是在Android 11及以後的系統中,每個視窗/活動/碎片都將擁有自己的獨立圖層級別,從而增強了效能和隱私管理。
    • 程式碼示例
      // 建立Layer
      Layer layer = mSurface.getLayer();
      layer.setX(100);
      layer.setY(100);
      layer.setAlpha(0.5f);
      // 在Layer上繪製影像和文字
      Canvas canvas = layer.lockCanvas();
      canvas.drawBitmap(bitmap, 0, 0, paint);
      canvas.drawText(text, 30, 100, paint);
      layer.unlockCanvasAndPost(canvas);
  6. HardwareComposer
    • HardwareComposer是Android系統中的硬體合成器,作為HWUI的主要介面之一。
    • 它的作用是在GPU輸出影像到螢幕之前,對多個應用程式的渲染結果進行混合和組合,從而形成最終的顯示內容。
    • 在硬體合成情況下,不需要將應用程式的UI渲染成一個幀快取(FrameBuffer)並上傳到系統RAM,從而減少記憶體和匯流排頻寬的負擔。
    • 程式碼示例
      RoutingTable routingTable = hwcomposer.createRoutingTable();
      routingTable.setOutputConfig(new OutputConfiguration(mDisplayToken, Display.DEFAULT_DISPLAY));
      Destination destination = routingTable.createDestination();
      destination.setColorMode(ColorMode.SRGB);
      destination.setBufferStream(bufferStream);
      surfaceFlinger.setTransactionState(routingTable.getTransaction());
      surfaceFlinger.applyTransaction();
  7. Threaded Rendering(多執行緒渲染):
    • 為了最大化利用CPU效能,HWUI採用了多執行緒渲染模式。
    • 通常包括UI執行緒和RenderThread(RT執行緒)。UI執行緒負責View的繪製邏輯和將繪製命令打包成Skia的繪製命令儲存到DisplayList;RT執行緒則負責取出這些繪製命令並執行實際的渲染操作。

三、工作流程

  1. UI執行緒繪製:
    • 當View需要被繪製時,UI執行緒會呼叫相應的繪製方法(如onDraw())。
    • 這些繪製方法透過Canvas類提供的介面進行繪製操作,Canvas的繪製命令會被轉化為Skia的繪製命令並儲存到DisplayList中。
  2. RenderThread渲染:
    • RenderThread從DisplayList中取出繪製命令,並透過OpenGL ES介面將這些命令傳送給GPU執行。
    • GPU完成繪製後,將渲染結果輸出到螢幕上。
  3. 效能最佳化:
    • HWUI還採用了多種效能最佳化技術,如延時渲染列表(Deferred Display List)、繪製命令合併(Draw Op Batching)等。
    • 這些技術透過減少GPU的呼叫次數、最佳化渲染狀態切換等方式來提高渲染效率。

四、總結

Android HWUI透過利用GPU進行硬體加速渲染,顯著提高了Android系統的UI渲染效能和流暢度。它透過Skia圖形庫、OpenGL ES介面、DisplayList、RenderNode以及多執行緒渲染等技術手段實現了高效的UI渲染過程。同時,HWUI還不斷引入新的效能最佳化技術來進一步提升渲染效率。

相關文章