?? 函數load也是實現在文件hardware/libhardware/hardware.c文件中,如下所示:
static?int?load(const?char?*id,??????????const?char?*path,??????????const?struct?hw_module_t?**pHmi)??{??????int?status;??????void?*handle;??????struct?hw_module_t?*hmi;??????????????????handle?=?dlopen(path,?RTLD_NOW);??????if?(handle?==?NULL)?{??????????char?const?*err_str?=?dlerror();??????????LOGE("load:?module=%s\n%s",?path,?err_str?err_str:"unknown");??????????status?=?-EINVAL;??????????goto?done;??????}??????????????const?char?*sym?=?HAL_MODULE_INFO_SYM_AS_STR;??????hmi?=?(struct?hw_module_t?*)dlsym(handle,?sym);??????if?(hmi?==?NULL)?{??????????LOGE("load:?couldn't?find?symbol?%s",?sym);??????????status?=?-EINVAL;??????????goto?done;??????}??????????????if?(strcmp(id,?hmi->id)?!=?0)?{??????????LOGE("load:?id=%s?!=?hmi->id=%s",?id,?hmi->id);??????????status?=?-EINVAL;??????????goto?done;??????}????????hmi->dso?=?handle;??????????????status?=?0;????????done:??????if?(status?!=?0)?{??????????hmi?=?NULL;??????????if?(handle?!=?NULL)?{??????????????dlclose(handle);??????????????handle?=?NULL;??????????}??????}?else?{??????????LOGV("loaded?HAL?id=%s?path=%s?hmi=%p?handle=%p",??????????????????id,?path,?*pHmi,?handle);??????}????????*pHmi?=?hmi;????????return?status;??}?? ? ? ? ? 在Linux系統中,后綴名為"so"的文件為動態鏈接庫文件,可能通過函數dlopen來加載到內存中。硬件抽象層模塊編寫規范規定每一個硬件抽象層模塊都必須導出一個符號名稱為HAL_MODULE_INFO_SYM_AS_STR的符號,而且這個符號必須是用來描述一個類型為hw_module_t的結構體的。 ? ? ? ? HAL_MODULE_INFO_SYM_AS_STR是一個宏,定義在文件hardware/libhardware/include/hardware/hardware.h文件中,如下所示: #define?HAL_MODULE_INFO_SYM_AS_STR??"HMI"?? ?? ? ? 將Gralloc模塊加載到內存中來之后,就可以調用函數dlsym來獲得它所導出的符號HMI。由于這個符號指向的是一個hw_module_t結構體,因此,最后函數load就可以強制地將這個符號轉換為一個hw_module_t結構體指針,并且保存在輸出參數pHmi中返回給調用者。調用者獲得了這個hw_module_t結構體指針之后,就可以創建一個gralloc設備或者一個fb設備。
?? ? ? 模塊Gralloc實現在目錄hardware/libhardware/modules/gralloc中,它導出的符號HMI定義在文件hardware/libhardware/modules/gralloc/gralloc.cpp文件中,如下所示:
static?struct?hw_module_methods_t?gralloc_module_methods?=?{??????????open:?gralloc_device_open??};????struct?private_module_t?HAL_MODULE_INFO_SYM?=?{??????base:?{??????????common:?{??????????????tag:?HARDWARE_MODULE_TAG,??????????????version_major:?1,??????????????version_minor:?0,??????????????id:?GRALLOC_HARDWARE_MODULE_ID,??????????????name:?"Graphics?Memory?Allocator?Module",??????????????author:?"The?Android?Open?Source?Project",??????????????methods:?&gralloc_module_methods??????????},??????????registerBuffer:?gralloc_register_buffer,??????????unregisterBuffer:?gralloc_unregister_buffer,??????????lock:?gralloc_lock,??????????unlock:?gralloc_unlock,??????},??????framebuffer:?0,??????flags:?0,??????numBuffers:?0,??????bufferMask:?0,??????lock:?PTHREAD_MUTEX_INITIALIZER,??????currentBuffer:?0,??};?? ?? ? ??HAL_MODULE_INFO_SYM也是一個宏,它的值是與宏HAL_MODULE_INFO_SYM_AS_STR對應的,它也是定義在文件hardware/libhardware/include/hardware/hardware.h文件中,如下所示:
圖1 private_module_t結構體定義
?? ?結構體private_module_t的第一個成員變量base指向一個gralloc_module_t結構體,而gralloc_module_t結構體的第一個成員變量common又指向了一個hw_module_t結構體,這意味著,指向一個private_module_t結構體的指針同時可以用作一個gralloc_module_t或者hw_module_t結構體提針來使用。事實上,這是使用C語言來實現的一種繼承關系,等價于結構體private_module_t繼承結構體gralloc_module_t,而結構體gralloc_module_t繼承hw_module_t結構體。這樣,我們就可以把在Gralloc模塊中定義的符號HAL_MODULE_INFO_SYM看作是一個hw_module_t結構體。
? ? ? ? hw_module_t結構體有一個重要的成員變量methods,它的類型為hw_module_methods_t,它用來描述一個HAL模塊的操作方法列表。結構體hw_module_methods_t只定義有一個操作方法open,用來打開一個指定的設備。在Gralloc模塊中,用來打開指定設備的函數被指定為gralloc_device_open,通過這個函數就可以打開Gralloc模塊中的gralloc或者fb設備,后面我們再詳細分析。
本文轉自 Luoshengyang 51CTO博客,原文鏈接:http://blog.51cto.com/shyluo/967062,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(2)...的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。