一、GPU硬件加速
1、概述
GPU英文全稱Graphic Processing Unit,中文翻譯為“圖形處理器”。與CPU不同,GPU是專門為處理圖形任務而產生的芯片。
在GPU出現之前,CPU一直負責著所有的運算工作,CPU的架構是有利於X86指令集的串行架構,CPU從設計思路上適合盡可能快的完成一個任務。但當面對類似多媒體、圖形圖像處理類型的任務時,就顯得力不從心。因為在多媒體計算中通常要求更高的運算密度、多並發線程和頻繁地存儲器訪問;顯然當你打游戲時,屏幕上的動畫是需要實時刷新的,這些都需要頻繁的計算、存取動作;如果CPU不能及時響應,那麼屏幕就會顯得很卡……你的隊友可能會發一句……我等的花都謝了,你咋還不動呢……
為了專門處理多媒體的計算、存儲任務,GPU就應運而生了,GPU中自帶處理器和存儲器,以用來專門計算和存儲多媒體任務。
對於Andorid來講,在API 11之前是沒有GPU的概念的,在API 11之後,在程序集中加入了對GPU加速的支持,在API 14之後,硬件加速是默認開啟的!我們可以顯式地強制圖像計算時使用GPU而不使用CPU.
在CPU繪制和GPU繪制時,在流程上是有區別的:
在基於軟件的繪制模型下,CPU主導繪圖,視圖按照兩個步驟繪制:讓View層次結構失效繪制View層次結構在基於硬件加速的繪制模式下,GPU主導繪圖,繪制按照三個步驟繪制:
讓View層次結構失效記錄、更新顯示列表繪制顯示列表可以看到在GPU加速時,流程中多了一項“記錄、更新顯示列表”,它表示在第一步View層次結構失效後,並不是直接開始逐層繪制,而是首先把這些View的繪制函數作為繪制指令記錄一個顯示列表中,然後再讀取顯示列表中的繪制指令調用OpenGL相關函數完成實際繪制。所以在GPU加速時,實際是使用OpenGL的函數來完成繪制的。
所以使用GPU加速的優點顯而易見:硬件加速提高了Android系統顯示和刷新的速度;
它有缺點也顯而易見:
1、 兼容性問題:由於是將繪制函數轉換成OpenGL命令來繪制,定然會存在OpenGL並不能完全支持原始繪制函數的問題,所以這就會造成在打開GPU加速時,效果會失效的問題。
2、內存消耗問題:由於需要OpenGL的指令,所以需要把系統中的OpenGL相關的包加載到內存中來,所以單純OpenGL API調用就會占用8MB,而實際上會占用更多內存;
3、電量消耗問題:多使用了一個部件,當然會更耗電……
下圖顯示了一些特殊函數硬件加速開始支持的平台等級:(紅叉表示任何平台都不支持,不在列表中的默認在API 11就開始支持)
我再重復一遍,上面我們涉及了兩個API等級,在API 11以後,在程序集中加入了對GPU加速的支持,在API 14之後,硬件加速是默認開啟的!也就是說在API 11——API 13雖然是支持硬件加速的,但是默認是關閉的。
2、禁用GPU硬件加速方法
那麼問題就來了,如果你的APP跑在API 14版本以後,而你洽好要用那些不支持硬件加速的函數要怎麼辦?
那就只好禁用硬件加速喽,針對不同類型的東東,Android給我們提供了不同的禁用方法:
硬件加速分全局(Application)、Activity、Window、View 四個層級
1.在AndroidManifest.xml文件為application標簽添加如下的屬性即可為整個應用程序開啟/關閉硬件加速:
2.在Activity 標簽下使用 hardwareAccelerated 屬性開啟或關閉硬件加速:
3. 在Window 層級使用如下代碼開啟硬件加速:(Window層級不支持關閉硬件加速)
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
4.View 級別如下關閉硬件加速:(view 層級上不支持開啟硬件加速)
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
或者使用android:layerType=”software”來關閉硬件加速:比如
二、setXfermode(Xfermode xfermode)之AvoidXfermode
這個函數是圖像混合裡最難的一個了,它的功能也是相當強大的,這個模式叫做圖形混合模式。
與setColorFilter一樣,派生自Xfermode的有三個類:
1、概述——基本流程
從上面可以看出,派生自Xfermode的有AvoidXfermode,PixelXorXfermode,PorterDuffXfermode;
從硬件加速不支持的函數列表中,我們可以看到AvoidXfermode,PixelXorXfermode是完全不支持的,而PorterDuffXfermode是部分不支持的。