Freescale MX51平台的透明處理根據bpp(bits_per_pixel)不同,處理方式有所不同。
透明處理涉及到兩個圖層的合并,這個合併作業是MX51 IPU的DP(Display process)模組來進行的。
為mx51 datasheet中的DP 微觀架構圖
的中Combining Unit就是用來實現兩個圖層的合并,DP有兩個input FIFOs用來傳輸full 圖層和partial圖層的資料。在傳入Combining Unit之前,還會做CSC(Color space convert)
Combining Unit
Combining Unit執行full和partial圖層的合併作業,這兩個圖層可以是graphics(UI)或者video圖層,一般來講,我們是指video層和UI層的合并。
在合并過程中,有如下四個因素
- 本地alpha參數:bpp(bits_per_pixel) = 32,每一個pixel中32bits中有8bits是alpha分量
- 全域alpha參數:bpp=16,相對於本地alpha把alpha分量儲存在每一個pixel中,全域alpha需要設定DP_COM_CONF的DP_GWAM為global alpha模式
- color key:首先color key是優先於alpha的,如果使能了DP_GWCKE_SYNC,那麼在combining過程中,優先查看這個pixel是否符合設定的color,符合則上層像素無效並且底層像素透明出來,並且忽略掉alpha計算;不符合則進行alpha計算
- 圖層順序: full在partial圖層之上,或者partial在full圖層之上
Alpha 計算公式
OP = BG*(1 - a) + FG*a
BG和FG是上下兩層的pixels;通過DP_GWSEL選擇BG是來自full層還是partial層。
a= (A+floor(A/128))/256 alpha值
A 全域或者本地alpha參數
透明代碼實現
首先考慮bpp=16的情況,bpp16,pixel資料只包含rgb或者yuv分量,並不包含透明參數alpha。
一般情況下video資料在下層,graphics(UI)資料在上層,在播放video時,需要把UI顯示在video上面,同時UI看起來好像有透明效果。
可設定framebuffer如下:
gbl_alpha.alpha = 64;
gbl_alpha.enable = 1;
int ret = ioctl(fd, MXCFB_SET_GBL_ALPHA, &gbl_alpha);
if(ret <0) {
LOGE("Error!MXCFB_SET_GBL_ALPHA failed!");
return -1;
}
struct mxcfb_color_key key;
key.enable = 1;
key.color_key = 0x00000000; // Black
ret = ioctl(fd, MXCFB_SET_CLR_KEY, &key);
if(ret <0) {
LOGE("Error!Colorkey setting failed for dev ");
return -1;
}
graphics(UI)是Android上層在一個全黑的畫布(canvas)上,畫出介面的,在和video合并時,要求未畫介面的部分是透明露出video,這是通過使能color key並設定匹配值為黑色(0x00000000)。但是這種實現在架構上是不完善的,因為如果畫介面是包含了黑色,那麼黑色介面部分也會透出底層video。
對於不匹配color key的部分,Combining Unit做alpha處理,這樣UI看起來好像有透明效果了。
如果不希望UI透明,可disable 全域alpha設定如下:
gbl_alpha.alpha = dummy_value;
gbl_alpha.enable = 0;
ioctl(fd, MXCFB_SET_GBL_ALPHA, &gbl_alpha);
或者
gbl_alpha.alpha = 255;
gbl_alpha.enable = 1;
ioctl(fd, MXCFB_SET_GBL_ALPHA, &gbl_alpha);
對於bpp(bits_per_pixel) = 32,那麼透明需要的alpha變數包含在每一個pixel資料裡面,只需如下設定framebuffer
struct mxcfb_loc_alpha l_alpha;
l_alpha.enable = true;
l_alpha.alpha_in_pixel = true;
if (ioctl(fd, MXCFB_SET_LOC_ALPHA, &l_alpha) < 0) {
printf("Set local alpha failed\n");
close(fd);
return -errno;
}
而上層畫介面服務需要處理每一個pixel,在pixel資料中加入alpha分量。