日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

c语言调用android surface,Android GUI SurfaceFlinger

發(fā)布時間:2025/3/12 Android 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言调用android surface,Android GUI SurfaceFlinger 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文涉及的源代碼基于 Android-7.1.1r。

一、Android GUI 框架

SurfaceFlinger 是 Android GUI 的核心,但是從 OpenGL_ES 的角度來看,它也只是個“應用程序”。Android 的顯示系統(tǒng)大致框架圖下圖所示:

GUI_STRUCT.png

下面就“由下向上”來逐一分析該框架。

(1) 顯示驅動

Linux 內(nèi)核提供了統(tǒng)一的 framebuffer 顯示驅動。設備節(jié)點是 /dev/graphics/fb* 或 /dev/fb*,而 fb0 表示第一個 Monitor,當前系統(tǒng)實現(xiàn)中只用到了一個顯示屏。

(2) HAL 層

Android 的 HAL 層提供了 Gralloc,包括 fb 和 gralloc 兩個設備。

fb 負責打開內(nèi)核中的 framebuffer,初始化配置,并提供 post,setSwapIntervel 等操作接口;

gralloc 用于管理幀緩沖區(qū)的分配和釋放。

HAL 層還包含另一個重要模塊 —— “Composer”,它為廠商自定制“UI合成”提供了接口。Composer 的直接使用者是 SurfaceFlinger 中的 HWComposer,HWComposer 除了負責管理 Composer 的 HAL 模塊外,還負責 VSync 信號(軟件、硬件)的產(chǎn)生和控制。

(3) FramebufferNativeWindow

FramebufferNativeWindow 是負責 OpenGL ES(通用函數(shù)庫) 在 Android 平臺上本地化的中介之一,它將 Android 的窗口系統(tǒng)與 OpenGL ES 產(chǎn)生聯(lián)系,為 OpenGL ES 配置本地窗口的是 EGL。

(4) EGL

EGL 負責為 OpenGL ES 配合本地窗口。OpenGL ES 更多的只是一個接口協(xié)議,具體實現(xiàn)即可以采用軟件,也可以采用硬件實現(xiàn),而 EGL 會去讀取 egl.cfg,并根據(jù)用戶的設置來動態(tài)加載 libagl(軟件實現(xiàn))或是 libhgl(硬件實現(xiàn))。

(5) DisplayDevice

SurfaceFlinger 中持有一個成員數(shù)組 mDisplays 用來描述系統(tǒng)中支持的各種"顯示設備",具體有那些 Display 是由 SurfaceFlinger 在 readyToRun 中進行判斷并賦值的。DisplayDevice 在初始化的時候會調用 eglGetDisplay,eglCreateWindowSurface 等接口,并利用 EGL 來完成 OpenGL ES 環(huán)境的搭建。

(6) OpenGL ES 模塊

很多模塊都可以調用 OpenGL ES 提供的 API,其中就包括 SurfaceFLinger 和 DisplayerDevice。

與 OpenGL ES 的相關的模塊分為以下幾類:

配置類:幫助 OpenGL ES 完成配置,包括 EGL,DisplayHardware 都屬這一類。

依賴類:OpenGL ES 要運行的起來所依賴的“本地化”的東西,在上圖中指的就是 FramebufferNativeWindow。

使用類:使用 OpenGL ES 的用戶,如 DisplayDevice 即扮演了使用者,又扮演了構建 OpenGL ES 的配置者。

二、HAL

HAL 是子系統(tǒng)(顯示系統(tǒng)、音頻系統(tǒng))與 Linux 內(nèi)核驅動之間的統(tǒng)一接口。

HAL 需要解決以下問題:

硬件的抽象;

接口的穩(wěn)定;

靈活的使用。

(1) 硬件抽象

HAL 多數(shù)使用 C 語言編寫,而 C 語言不是面向對象的,所以具體的“繼承”關系就沒有像 C++ 或是 Java 這類的面向對象的語言表現(xiàn)的那么直接。在 C 語言中要實現(xiàn)類似的“繼承”關系,只需要讓子類的第一個成員變量是父類結構即可。以 Gralloc 為例,它就是 hw_module_t 的子類,代碼如下:

typedef struct gralloc_module_t {

struct hw_module_t common; // 父類

// 結構體中定義函數(shù)指針(結構體中不能定義函數(shù))

int (*registerBuffer)(struct gralloc_module_t const* module,

buffer_handle_t handle);

int (*unregisterBuffer)(struct gralloc_module_t const* module,

buffer_handle_t handle);

int (*lock)(struct gralloc_module_t const* module,

buffer_handle_t handle, int usage,

int l, int t, int w, int h,

void** vaddr);

int (*unlock)(struct gralloc_module_t const* module,

buffer_handle_t handle);

int (*perform)(struct gralloc_module_t const* module,

int operation, ... );

int (*lock_ycbcr)(struct gralloc_module_t const* module,

buffer_handle_t handle, int usage,

int l, int t, int w, int h,

struct android_ycbcr *ycbcr);

int (*lockAsync)(struct gralloc_module_t const* module,

buffer_handle_t handle, int usage,

int l, int t, int w, int h,

void** vaddr, int fenceFd);

int (*unlockAsync)(struct gralloc_module_t const* module,

buffer_handle_t handle, int* fenceFd);

int (*lockAsync_ycbcr)(struct gralloc_module_t const* module,

buffer_handle_t handle, int usage,

int l, int t, int w, int h,

struct android_ycbcr *ycbcr, int fenceFd);

void* reserved_proc[3];

} gralloc_module_t;

(2) 接口的穩(wěn)定

HAL 中的接口必須是穩(wěn)定不變的,Android 系統(tǒng)中已經(jīng)預定好了這些接口,如下圖所示(源碼位置:hardware/libhardware/include/hardware):

HAL接口.png

(3) 靈活的使用

硬件生產(chǎn)商只要按照 Android 提供的硬件要求來實現(xiàn) HAL 接口,手機開發(fā)商只需要移植硬件生產(chǎn)商提供的 HAL 庫就可以了。

三、Android 終端顯示設備 ———— Gralloc 和 Framebuffer

Framebuffer 是 Linux 內(nèi)核提供的圖形硬件的抽象描述,它占用了系統(tǒng)內(nèi)存的一部分,是一塊包含屏幕顯示信息的緩沖區(qū)。在 Android 中,Framebuffer 提供的設備文件節(jié)點是 /dev/graphics/fb*。這里以 sony Xperia 為例,它的 fb 節(jié)點如下圖所示:

Sony_Xperia_fb.png

Android 的子系統(tǒng)不會直接使用內(nèi)核驅動,而是由 HAL 層來間接引用底層框架。顯示系統(tǒng)也是一樣,它通過 HAL 層來做操作幀緩沖區(qū),而完成這一中介任務的就是 Gralloc。

3.1、Gralloc 模塊的加載

Gralloc 對應的模塊是在 FramebufferNativeWindow(GUI 結構圖中位于 Grlloc 上方) 的構造函數(shù)中加載的(在 Androdi-7.1.1 中是通過 Gralloc1.cpp 進行加載的),即:

int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); //

hw_get_module 是上層使用(FramebufferNativeWindow)者加載 HAL 庫的入口。lib 庫有以下幾種形式;

gralloc.[ro.hardware].so

gralloc.[ro.product.board].so

gralloc.[ro.board.platform].so

gralloc.[ro.arch].so

當以上文件都不存在時,就使用默認的:

gralloc.default.so

源碼位置:hardware/libhardware/modules/gralloc/,由 gralloc.cpp,framebuffer.cpp 和 mapper.cpp 三個主要文件編譯而成。

3.2、Gralloc 提供的接口

Gralloc 是 hw_module_t 的子類,hw_module_t 代碼如下:

typedef struct hw_module_t {

uint32_t tag;

uint16_t module_api_version;

#define version_major module_api_version

uint16_t hal_api_version;

#define version_minor hal_api_version

const char *id;

const char *name;

const char *author;

struct hw_module_methods_t* methods; // hw_module_t 中必須提供

void* dso;

#ifdef __LP64__

uint64_t reserved[32-7];

#else

uint32_t reserved[32-7];

#endif

} hw_module_t;

typedef struct hw_module_methods_t {

// 函數(shù)指針,用于打開設備

int (*open)(const struct hw_module_t* module, const char* id,

struct hw_device_t** device);

} hw_module_methods_t;

任何硬件設備的 HAL 庫都必須實現(xiàn) hw_module_methods_t,該結構體中只有一個函數(shù)指針變量,也就是 open,由于函數(shù)體內(nèi)不能定義函數(shù),所以這里使用了函數(shù)指針。當上層使用者調用 hw_get_module 時,系統(tǒng)首先會在指定目錄下加載正確的 HAL 庫,然后通過 open 函數(shù)打開指定的設備。這里 open 方法對應的實現(xiàn)是 gralloc_device_open()@gralloc.cpp。open接口可以可以幫助上層使用者打開兩種設備:

define GRALLOC_HARDWARE_FB0:主屏

define GRALLOC_HARDWARE_GPU0:負責圖形緩沖區(qū)的分配和釋放

define 前有“#”,由于格式問題,這里沒有打出。

下面看 gralloc_device_open() 的實現(xiàn):

// gralloc.cpp

int gralloc_device_open(const hw_module_t* module, const char* name,

hw_device_t** device)

{

int status = -EINVAL;

// 打開 gralloc 設備或是打開 fb 設備。

if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {

gralloc_context_t *dev;

dev = (gralloc_context_t*)malloc(sizeof(*dev));

/* initialize our state here */

memset(dev, 0, sizeof(*dev));

/* initialize the procs */

dev->device.common.tag = HARDWARE_DEVICE_TAG;

dev->device.common.version = 0;

dev->device.common.module = const_cast(module);

dev->device.common.close = gralloc_close;

dev->device.alloc = gralloc_alloc;

dev->device.free = gralloc_free;

*device = &dev->device.common;

status = 0;

} else {

status = fb_device_open(module, name, device); // 打開 Framebuffer

}

return status;

}

下面看 framebuffer 設備的打開過程:

int fb_device_open(hw_module_t const* module, const char* name,

hw_device_t** device)

{

int status = -EINVAL;

if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {

/* initialize our state here */

fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev)); // 分配 hw_device_t 空間,這只是一個“殼”

memset(dev, 0, sizeof(*dev)); // 初始化

/* initialize the procs */

dev->device.common.tag = HARDWARE_DEVICE_TAG;

dev->device.common.version = 0;

dev->device.common.module = const_cast(module);

// 核心接口

dev->device.common.close = fb_close;

dev->device.setSwapInterval = fb_setSwapInterval;

dev->device.post = fb_post;

dev->device.setUpdateRect = 0;

private_module_t* m = (private_module_t*)module;

status = mapFrameBuffer(m); // 內(nèi)存映射 mmap

if (status >= 0) {

int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);

int format = (m->info.bits_per_pixel == 32)

? (m->info.red.offset ? HAL_PIXEL_FORMAT_BGRA_8888 : HAL_PIXEL_FORMAT_RGBX_8888)

: HAL_PIXEL_FORMAT_RGB_565;

const_cast(dev->device.flags) = 0;

const_cast(dev->device.width) = m->info.xres;

const_cast(dev->device.height) = m->info.yres;

const_cast(dev->device.stride) = stride;

const_cast(dev->device.format) = format;

const_cast(dev->device.xdpi) = m->xdpi;

const_cast(dev->device.ydpi) = m->ydpi;

const_cast(dev->device.fps) = m->fps;

const_cast(dev->device.minSwapInterval) = 1;

const_cast(dev->device.maxSwapInterval) = 1;

*device = &dev->device.common; // 核心

}

}

return status;

}

其中 fb_context_t 是 framebuffer 內(nèi)部使用的一個類,它包含了眾多信息,而最終返回的 device 只是其內(nèi)部的 device.common。這種“通用和差異”并存的編碼風格在 HAL 層非常常見。

fb_context_t 唯一的成員就是 framebuffer_device_t,這是對 frambuffer 設備的統(tǒng)一描述。

struct fb_context_t {

framebuffer_device_t device;

};

一個標準的 fb 設備通常要提供如下的函數(shù)實現(xiàn):

int(post)(struct framebuffer_device_t dev, buffer_handle_t buffer);

將 buffer 數(shù)據(jù) post 到顯示屏上。要求 buffer 必須與屏幕尺寸一致,并且沒有被 locked。這樣的話

buffer 內(nèi)容將在下一次 VSYNC 中被顯示出來。

int(setSwapInterval)(struct framebuffer_device_t window, int interval);

設置兩個緩沖區(qū)交換的時間間隔

int(setUpdateRect)(struct framebuffer_device_t window, int left, int top, int width, int height);

設置刷新區(qū)域,需要 framebuffer 驅動支持“update-on-demand”。也就是說在這個區(qū)域外的數(shù)據(jù)很可能

被認為無效。

framebuffer_device_t 中的重要成員變量:

typedef struct framebuffer_device_t {

struct hw_device_t common;

const uint32_t flags; // 用來記錄系統(tǒng)幀緩沖區(qū)的標志

const uint32_t width; // 用來描述設備顯示屏的寬度

const uint32_t height; // 用來描述設備顯示屏的高度

const int stride; // 用來描述設備顯示屏的一行有多少個像素點

const int format; // 用來描述系統(tǒng)幀緩沖區(qū)的像素格式

const float xdpi; // 用來描述設備顯示屏在寬度上的密度

const float ydpi; // 用來描述設備顯示屏在高度上的密度

const float fps; // 用來描述設備顯示屏的刷新頻率

const int minSwapInterval; // 用來描述幀緩沖區(qū)交換前后兩個圖形緩沖區(qū)的最小時間間隔

const int maxSwapInterval; // 用來描述幀緩沖區(qū)交換前后兩個圖形緩沖區(qū)的最大時間間隔

int reserved[8];//保留

// 用來設置幀緩沖區(qū)交換前后兩個圖形緩沖區(qū)的最小和最大時間間隔

int (*setSwapInterval)(struct framebuffer_device_t* window,int interval);

// 用來設置幀緩沖區(qū)的更新區(qū)域

int (*setUpdateRect)(struct framebuffer_device_t* window,int left, int top, int width, int height);

// 用來將圖形緩沖區(qū)buffer的內(nèi)容渲染到幀緩沖區(qū)中去

int (*post)(struct framebuffer_device_t* dev, buffer_handle_t buffer);

// 用來通知 fb 設備,圖形緩沖區(qū)的組合工作已經(jīng)完成

int (*compositionComplete)(struct framebuffer_device_t* dev);

void (*dump)(struct framebuffer_device_t* dev, char *buff, int buff_len);

int (*enableScreen)(struct framebuffer_device_t* dev, int enable);

// 保留

void* reserved_proc[6];

} framebuffer_device_t;

變 量

描 述

uint32_t flags

標志位,指示framebuffer 的屬性配置

uint32_t width; uint32_t height;

framebuffer 的寬和高,以像素為單位

int format

framebuffer 的像素格式,比如:HAL_PIXEL_FORMAT_RGBA_8888,HAL_PIXEL_FORMAT_RGBX_8888,HAL_PIXEL_FORMAT_RGB_888,HAL_PIXEL_FORMAT_RGB_565 等等

float xdpi;float ydpi;

x和y軸的密度(pixel per inch)

float fps

屏幕的每秒刷新頻率,假如無法正常從設備獲取的話,默認設置為 60Hz

int minSwapInterval;int maxSwapInterval;

該 framebuffer 支持的最小和最大緩沖交換時間

我們以下面簡圖來小結對 Gralloc 的分析:

[圖片上傳失敗...(image-f944da-1542183518291)]

四、Android 本地窗口

Native Window為OpenGL與本地窗口系統(tǒng)之間搭建了橋梁。整個GGUI系統(tǒng)至少需要兩種本地窗口:

面向管理者(SurfaceFlinger)

SurfaceFlinger 是系統(tǒng)中所有 UI 界面的管理者,需要直接或間接的持有“本地窗口”,此本地窗口是

FramebufferNativeWindow(4.2+ 后被廢棄)。

面向應用程序

這類本地窗口是 Surface。

正常情況按照 SDK 向導生成 APK 應用程序,是采用 Skia 等第三方圖形庫,而對于希望使用 OpenGL ES 來完成復雜界面渲染的應用開發(fā)者來說,Android 也提供封裝的 GLSurfaceView(或其他方式)來實現(xiàn)圖形顯示。

4.1、FramebufferNativeWindow

EGL 需要根據(jù)本地窗口來為 OpenGL/OpenGL ES 創(chuàng)造環(huán)境,但是不論哪一類本地窗口都需要和“本地窗口類型”保持一致。

// /frameworks/native/opengl/include/EGL/eglplatform.h

...

typedef HWND EGLNativeWindowType;

#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */

typedef int EGLNativeDisplayType;

typedef void *EGLNativeWindowType;

typedef void *EGLNativePixmapType;

#elif defined(__ANDROID__) || defined(ANDROID) // Android 系統(tǒng)

struct ANativeWindow;

struct egl_native_pixmap_t;

typedef struct ANativeWindow* EGLNativeWindowType;

...

#elif defined(__unix__) // unix 系統(tǒng)

...

typedef Window EGLNativeWindowType;

#else

#error "Platform not recognized"

#endif

...

EGLNativeWindowType 在不同系統(tǒng)中對應不同的數(shù)據(jù)類型,而在 Android 中對應的是 ANativeWindow 指針。

// /system/core/include/system/window.h

struct ANativeWindow

{

...

const uint32_t flags; // 與 Surface 或 update 有關的屬性

const int minSwapInterval; // 最小交換時間間隔

const int maxSwapInterval; // 最大交換時間間隔

const float xdpi; // 水平方向密度 dpi

const float ydpi; // 垂直方向密度 dpi

intptr_t oem[4];

...

// 設置交換時間

int (*setSwapInterval)(struct ANativeWindow* window,

int interval);

// 向本地窗口查詢相關信息

int (*query)(const struct ANativeWindow* window,

int what, int* value);

// 用于執(zhí)行本地窗口的相關操作

int (*perform)(struct ANativeWindow* window,

int operation, ... );

int (*cancelBuffer_DEPRECATED)(struct ANativeWindow* window,

struct ANativeWindowBuffer* buffer);

// EGL 通過該接口來申請 buffer

int (*dequeueBuffer)(struct ANativeWindow* window,

struct ANativeWindowBuffer** buffer, int* fenceFd);

// EGL 對 buffer 渲染完成后就調用該接口,來 unlock 和 post buffer

int (*queueBuffer)(struct ANativeWindow* window,

struct ANativeWindowBuffer* buffer, int fenceFd);

// 取消一個已經(jīng) dequeue 的 buffer

int (*cancelBuffer)(struct ANativeWindow* window,

struct ANativeWindowBuffer* buffer, int fenceFd);

};

ANativeWindow 更像一份“協(xié)議”,規(guī)定了本地窗口的形態(tài)和功能。下面來分析 FramebufferNativeWindow 是如何履行“協(xié)議”的。

(1) FramebufferNativeWindow 構造函數(shù)

FramebufferNativeWindow 構造函數(shù)的功能包括:

加載 Gralloc 模塊(GRALLOC_HARDWARE_MODULE_ID)。

打開 fb 和 gralloc(gpu0) 設備,打開后由 fbDev 和 grDev 管理。

根據(jù)設備屬性為 FramebufferNativeWindow 賦初值。

根據(jù) FramebufferNativeWindow 的實現(xiàn)來填充 ANativeWindow 中的“協(xié)議”。

其他必要的初始化。

所有申請到的緩沖區(qū)都由 FramebufferNativeWindow 中的 buffers[] 來記錄,每個元素是一個 NativeBuffer,該類繼承了 ANativeWindowBuffer, 該類的聲明如下:

// /system/core/include/system/window.h

typedef struct ANativeWindowBuffer

{

...

int width;

int height;

int stride;

int format;

int usage;

void* reserved[2];

buffer_handle_t handle; // 代表內(nèi)存塊的句柄

void* reserved_proc[8];

} ANativeWindowBuffer_t;

(2) dequeueBuffer

int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,

ANativeWindowBuffer** buffer)

{

FramebufferNativeWindow* self = getSelf(window);

Mutex::Autolock _l(self->mutex);

// 從 FramebufferNativeWindow 對象中取出 fb 設備描述符,在構造 FramebufferNativeWindow 對象時,已經(jīng)打開了 fb 設備

framebuffer_device_t* fb = self->fbDev;

// 計算當前申請的圖形緩沖區(qū)在 buffers 數(shù)組中的索引,同時將下一個申請的 buffe r的索引保存到 mBufferHead 中

int index = self->mBufferHead++;

// 如果申請的下一個 buffer 的索引大于或等于 buffer 總數(shù),則將下一個申請的 buffer 索引設置為 0,這樣就實現(xiàn)了對 buffer 數(shù)組的循環(huán)管理

if (self->mBufferHead >= self->mNumBuffers)

self->mBufferHead = 0;

// 如果當前沒有空閑的 buffer,即 mNumFreeBuffers = 0,則線程睡眠等待 buffer 的釋放

while (!self->mNumFreeBuffers) {

self->mCondition.wait(self->mutex);

}

// 存在了空閑 buffer,線程被喚醒繼續(xù)執(zhí)行,由于此時要申請一塊 buffer,因此空閑 buffer 的個數(shù)又需要減 1

self->mNumFreeBuffers--;

// 保存當前申請的 buffer 在緩沖區(qū)數(shù)組中的索引位置

self->mCurrentBufferIndex = index;

// 得到 buffer 數(shù)組中的 NativeBuffer 對象指針

*buffer = self->buffers[index].get();

return 0;

}

dequeueBuffer 函數(shù)就是從 FramebufferNativeWindow 創(chuàng)建的包含 2 個圖形緩沖區(qū)的緩沖區(qū)隊列 buffers 中取出一塊空閑可用的圖形 buffer,如果當前緩沖區(qū)隊列中沒有空閑的 buffer,則當前申請 buffer 線程阻塞等待,等待其他線程釋放圖形緩沖區(qū)。mNumFreeBuffers 用來描述可用的空閑圖形 buffer 個數(shù),index 記錄當前申請 buffer 在圖形緩沖區(qū)隊列中的索引位置,mBufferHead 指向下一次申請的圖形 buffer 的位置,由于我們是循環(huán)利用兩個緩沖區(qū)的,所以如果這個變量的值超過 mNumBuffers,就需要置 0。也就是說 mBufferHead 的值永遠只能是 0或者 1。

4.2、SurfaceView

Surface 也繼承了 ANativeWindow:

class Surface: public ANativeObjectBase{ ... }

Surface 是面向 Android 系統(tǒng)中所有 UI 應用程序的,即它承擔著應用進程中的 UI 顯示需求。

Surface 需要面向上層實現(xiàn)(主要是 Java 層)提供繪制圖像的畫板。SurfaceFlinger 需要收集系統(tǒng)中所有應用程序繪制的圖像數(shù)據(jù),然后集中顯示到物理屏幕上。Surface 需要扮演相應角色,本質上還是由 SurfaceFlinger 服務統(tǒng)一管理的,涉及到很多跨進程的通信細節(jié)。

下面來看 Surface 中的關鍵成員變量:

成員變量

說明

sp mGraphicsBufferProducer

Surface 核心變量

BufferSlot mSlots[32]

Surface 內(nèi)部存儲 buffer 的地方,BufferSlot 內(nèi)不包括:GraphicsBuffer 和 dirtyRegion,當用戶 dequeue 時將申請內(nèi)存

Surface 將通過 mGraphicBufferProducer 來獲取 buffer,這些緩沖區(qū)會被記錄在 mSlots 中數(shù)據(jù)中。mGraphicBufferProducer 這一核心成員的初始化流程如下:

ViewRootImpl 持有一個 Java 層的 Surface 對象(mSurface)。

ViewRootImpl 向 WindowManagerService 發(fā)起 relayout 請求,此時 mSurface 被賦予真正的有效值,

將輾轉生成的 SurfaceControl 通過S urface.copyFrom() 函數(shù)復制到 mSurface 中。

由此,Surface 由 SurfaceControl 管理,SurfaceControl 由 SurfaceComposerClient 創(chuàng)建。SurfaceComposerClient 獲得的匿名 Binder 是 ISurfaceComposer,其服務端實現(xiàn)是 SurfaceFlinger。而 Surface 依賴的 IGraphicBufferProducer 對象在 Service 端的實現(xiàn)是 BufferQueue。

class SurfaceFlinger :

public BinderService, // 在 ServiceManager 中注冊為 SurfaceFlinger

public BnSurfaceComposer, // 實現(xiàn)的接口卻叫 ISurfaceComposer

Buffer,Consumer,Producer 是“生產(chǎn)者-消費者”模型中的 3 個參與對象,如何協(xié)調好它們的工作是應用程序能否正常顯示UI的關鍵。Buffer 是 BufferQueue,Producer 是應用程序,Consumer 是 SurfaceFlinger。

五、BufferQueue

To be continued ....

總結

以上是生活随笔為你收集整理的c语言调用android surface,Android GUI SurfaceFlinger的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。