Android ‍Pixelflinger 研究

來源:互聯網
上載者:User

轉自 http://hi.baidu.com/aokikyon/blog/item/2e8ca6130db328906438db18.html

 

1. Pixelflinger簡介
Pixelflinger是Android系統中為OpenGL ES引擎提供的一套軟體渲染器(renderer)。系統啟動時通過查看開機記錄資訊可以擷取當前Pixelflinger的軟體版本(代碼)。Pixelflinger軟體版本隨著Android版本的升級而提高,目前最新的版本為1.3(基於Android2.2系統)。
I/SurfaceFlinger( 1931): OpenGL informations:
I/SurfaceFlinger( 1931): vendor    : Android
I/SurfaceFlinger( 1931): renderer : Android PixelFlinger 1.2
I/SurfaceFlinger( 1931): version   : OpenGL ES-CM 1.0
Pixelflinger作為軟體渲染器,為OpenGL ES引擎提供了一系列基礎繪圖功能。這些功能包括定義各種顏色格式像素位置、畫點畫線、繪製矩形及三角形、填充紋理等等。由於OpenGL ES相當於一個狀態機器,配置OpenGL ES狀態的函數也均由Pixelflinger提供。
Pixelflinger的原始碼位於system/core/libpixelflinger。
標頭檔位於system/core/include/libpixelflinger和system/core/include/private/pixelflinger。

2. Pixelflinger主要資料結構
Pixelflinger在標頭檔Ggl_context.h中定義了context_t結構體,用來儲存OpenGL ES狀態及資料內容。context_t結構體中包含GGLContext、state_t、shade_t、iterators_t、generated_vars_t等結構體。
GGLContext結構體中包含了Pixelflinger庫可提供給上層調用的一些函數介面,包括畫點畫線、繪製多邊形、配置OpenGL ES狀態機器等函數介面。
state_t結構體用來描述OpenGL ES狀態機器的狀態,包含多個子結構體,每個子結構體均負責處理一部分OpenGL ES功能。包括儲存貼圖及紋理、裁剪操作、光柵操作、混合操作、景深操作、霧化操作等功能。

3. Pixelflinger初始化
gglInit(GGLContext** context)
為context_t分配空間;
調用ggl_init_context(c);
ggl_init_context(context_t* c)
調用ggl_init_procs(c),將state_t結構體的函數指標與Pixelflinger.cpp中的函數掛鈎。
調用ggl_init_trap(c),配置OpenGL ES狀態機器的狀態。
調用ggl_init_scanline(c),主要將scanline函數與context_t的介面掛鈎。
調用ggl_init_texture(c),初始化紋理相關的狀態。
調用ggl_init_picker(c),空函數。
調用ggl_init_raster(c),將Raster.cpp中的函數與state_t結構體的函數指標掛鈎。
初始化其他資訊及抖動矩陣
ggl_init_procs(context_t* c)
ggl_init_procs 使用GGL_INIT_PROC宏進行函數與函數指標的掛鈎。
#define GGL_INIT_PROC(p, f)         p.f = ggl_ ## f;

4. GGLContext提供的主要函數介面
直接渲染函數
pointx、linex、recti、trianglex
裁剪函數
scissor
設定紋理和色彩緩衝
activeTexture
bindTexture
colorBuffer
readBuffer
depthBuffer
bindTextureLod
功能控制開關
enable
disable
enableDisable
指定片段顏色
shadeModel
color4xv
指定顏色迭代器
colorGrad12xv
指定Z座標迭代器
zGrad3xv
指定W座標迭代器
wGrad3xv
指定霧迭代器與顏色
fogGrad3xv
fogColor3xv
指定混合參數
blendFunc
blendFuncSeparate
紋理環境(包括四種紋理REPLACE / MODULATE / DECAL / BLEND)
texEnvi
texEnvxv
紋理參數(封裝及過濾)
texParameteri
紋理迭代器
texCoord2i
texCoord2x
為紋理ST座標使用塊浮點
texCoordGradScale8xv
texGeni
屏蔽函數
colorMask
depthMask
stencilMask
alpha函數
alphaFuncx
景深函數
depthFunc
邏輯操作介面
logicOp
清除函數
clear
clearColorx
clearDepthx
clearStencil
framebuffer操作
copyPixels
rasterPos2x 
rasterPos2i

5. Pixelflinger支援的顏色格式
Pixelflinger在Format.cpp中定義了所支援的顏色格式及像素的位置,常用的顏色格式主要有RGBA8888、RGBX8888、RGB565、BGRA8888。從結構體中可以看出,Alpha通道位於32-24位,屬於高位,可見RGBA8888使用的是大端順序。這裡定義的顏色格式只能夠被ANdroid的OpenGL ES使用,和通過Canvas繪製的映像無關。
static GGLFormat const gPixelFormatInfos[] =
{   //          Alpha    Red     Green   Blue
    { 0, 0, {{ 0, 0,   0, 0,   0, 0,   0, 0 }},        0 },   // PIXEL_FORMAT_NONE
    { 4, 32, {{32,24,   8, 0, 16, 8, 24,16 }}, GGL_RGBA },   // PIXEL_FORMAT_RGBA_8888
    { 4, 24, {{ 0, 0,   8, 0, 16, 8, 24,16 }}, GGL_RGB },   // PIXEL_FORMAT_RGBX_8888
    { 3, 24, {{ 0, 0,   8, 0, 16, 8, 24,16 }}, GGL_RGB },   // PIXEL_FORMAT_RGB_888
    { 2, 16, {{ 0, 0, 16,11, 11, 5,   5, 0 }}, GGL_RGB },   // PIXEL_FORMAT_RGB_565
    { 4, 32, {{32,24, 24,16, 16, 8,   8, 0 }}, GGL_RGBA },   // PIXEL_FORMAT_BGRA_8888
    { 2, 16, {{ 1, 0, 16,11, 11, 6,   6, 1 }}, GGL_RGBA },   // PIXEL_FORMAT_RGBA_5551
    { 2, 16, {{ 4, 0, 16,12, 12, 8,   8, 4 }}, GGL_RGBA },   // PIXEL_FORMAT_RGBA_4444
    { 1, 8, {{ 8, 0,   0, 0,   0, 0,   0, 0 }}, GGL_ALPHA},   // PIXEL_FORMAT_A8
    { 1, 8, {{ 0, 0,   8, 0,   8, 0,   8, 0 }}, GGL_LUMINANCE},//PIXEL_FORMAT_L8
    { 2, 16, {{16, 8,   8, 0,   8, 0,   8, 0 }}, GGL_LUMINANCE_ALPHA},// PIXEL_FORMAT_LA_88
    { 1, 8, {{ 0, 0,   8, 5,   5, 2,   2, 0 }}, GGL_RGB },   // PIXEL_FORMAT_RGB_332
    { 1, 16, {{ 0, 8,   0, 8,   0, 8,   0, 0 }}, GGL_Y_CB_CR_SP },// PIXEL_FORMAT_YCbCr_422_SP
    { 1, 12, {{ 0, 8,   0, 8,   0, 8,   0, 0 }}, GGL_Y_CB_CR_SP },// PIXEL_FORMAT_YCbCr_420_SP
    { 1, 16, {{ 0, 8,   0, 8,   0, 8,   0, 0 }}, GGL_Y_CB_CR_P }, // PIXEL_FORMAT_YCbCr_422_P
    { 1, 12, {{ 0, 8,   0, 8,   0, 8,   0, 0 }}, GGL_Y_CB_CR_P }, // PIXEL_FORMAT_YCbCr_420_P
    { 1, 16, {{ 0, 8,   0, 8,   0, 8,   0, 0 }}, GGL_Y_CB_CR_I }, // PIXEL_FORMAT_YCbCr_422_I
    { 1, 12, {{ 0, 8,   0, 8,   0, 8,   0, 0 }}, GGL_Y_CB_CR_I }, // PIXEL_FORMAT_YCbCr_420_I
    { 0, 0, {{ 0, 0,   0, 0,   0, 0,   0, 0 }},        0 },   // PIXEL_FORMAT_NONE
    { 0, 0, {{ 0, 0,   0, 0,   0, 0,   0, 0 }},        0 },   // PIXEL_FORMAT_NONE
    { 2, 16, {{ 0, 0, 16, 0,   0, 0,   0, 0 }}, GGL_DEPTH_COMPONENT},
    { 1, 8, {{ 8, 0, 0, 0,   0, 0,   0, 0 }}, GGL_STENCIL_INDEX },
    { 4, 24, {{ 0, 0, 24, 0,   0, 0,   0, 0 }}, GGL_DEPTH_COMPONENT},
    { 4, 8, {{ 32,24, 0, 0,   0, 0,   0, 0 }}, GGL_STENCIL_INDEX },
};

6. Pixelflinger的最佳化
1)通過最佳化context_t儲存空間,保證cache對齊以最佳化效能。context_t是Pixelflinger中最常用,最大的一個資料結構。

void* const base = malloc(sizeof(context_t) + 32);
    context_t *c = (context_t *)((ptrdiff_t(base)+31) & ~0x1FL);
    ggl_init_context(c);

2)通過Android.mk中的編譯選項最佳化
ifeq ($(TARGET_ARCH),arm)
# special optimization flags for pixelflinger
PIXELFLINGER_CFLAGS += -fstrict-aliasing -fomit-frame-pointer
endif
-fstrict-aliasing選項表示編譯器不會將不同類型的對象指向同一個地址。
-fomit-frame-pointer選項可以使編譯器在函數調用中節省fp寄存器以提高效率。

3)通過用彙編替代C語言函數直接最佳化效能
ifeq ($(TARGET_ARCH),arm)
PIXELFLINGER_SRC_FILES += t32cb16blend.S
endif

4)通過對ARM不同版本進行特殊最佳化
ifeq ($(TARGET_ARCH),arm)
LOCAL_ASFLAGS := -march=armv6
LOCAL_SRC_FILES := rotate90CW_4x4_16v6.S
LOCAL_MODULE := libpixelflinger_armv6
include $(BUILD_STATIC_LIBRARY)
endif

rotate90CW_4x4_16v6:
    // r0 = dst
    // r1 = src
    // r2 = dst stride in pixels
    // r3 = src stride in pixels
    stmfd   sp!, {r4,r5, r6,r7, r8,r9, r10,r11, lr}
    add     r14, r3, r3
    add     r12, r2, r2
    ldrd    r2, r3, [r1], r14
    ldrd    r4, r5, [r1], r14
    ldrd    r6, r7, [r1], r14
    ldrd    r8, r9, [r1]
    pkhbt   r10, r8, r6, lsl #16
    pkhbt   r11, r4, r2, lsl #16
    strd    r10, r11, [r0], r12 
    pkhtb   r10, r6, r8, asr #16
    pkhtb   r11, r2, r4, asr #16
    strd    r10, r11, [r0], r12 
    pkhbt   r10, r9, r7, lsl #16
    pkhbt   r11, r5, r3, lsl #16
    strd    r10, r11, [r0], r12 
    pkhtb   r10, r7, r9, asr #16
    pkhtb   r11, r3, r5, asr #16
    strd    r10, r11, [r0]
    ldmfd   sp!, {r4,r5, r6,r7, r8,r9, r10,r11, pc}

rotate90CW_4x4_16v6這個函數中使用了ARMv6架構才支援的pkhtb指令,以提高處理速度。

5)system/core/libpixelflinger/codeflinger中用C語言通過填充機器碼的形式實現了一些彙編操作,可以動態產生彙編函數。

6)網上有一些開源項目,通過使用ARMv7架構的Neon副處理器對效能進行最佳化。
http://code.google.com/p/0xdroid/issues/detail?id=57

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.