整個 Android 2.2的圖型模組, 不論是 2D, 3D應用程式運行, 只要是圖形相關的應用, 都需要配置 graphic buffer, 在 Android 中負責這工作的模組就是 gralloc HAL(gralloc 硬體抽象層).
Gralloc HAL 的程式碼在 /hardware/libhardware/modules/gralloc/Gralloc.cpp
動態連結庫 gralloc.default.so 位置在系統路徑 /system/lib/hw/
請看到 /frameworks/base/libs/SurfaceFlinger.cpp 的 readyToRun() 函式, Android SurfaceFlinger在這個函式裡初始化繪圖硬體. 在 readyToRun() 生成 DisplayHardware 物件時, DisplayHardware 的建構式會調用 Init() 函式, Init() 會生成FramebufferNativeWindow 物件, class FramebufferNativeWindow 的程式碼位於 :
/frameworks/base/libs/ui/FramebufferNativeWindow.cpp
/frameworks/base/include/ui/FramebufferNativeWindow.h
1. 調用 hw_get_module (GRALLOC_HARDWARE_MODULE_ID, &module)函式
在 hw_get_module()中調用dlopen()打開 gralloc.default.so並調用 dlsym()取得gralloc 模組的資訊(HMI), 此資訊用 hw_module_t 結構體存放:
hw_module_t 定義在 /hardware/libhardware/include/hardware/Hardware.h
01 typedef struct hw_module_t { 02 /** tag must be initialized to HARDWARE_MODULE_TAG */ 03 uint32_t tag; 04 /** major version number for the module */ 05 uint16_t version_major; 06 /** minor version number of the module */ 07 uint16_t version_minor; 08 /** Identifier of module */ 09 const char *id; 10 /** Name of this module */ 11 const char *name; 12 /** Author/owner/implementor of the module */ 13 const char *author; 14 /** Modules methods */ 15 struct hw_module_methods_t* methods; 16 /** module's dso */ 17 void* dso; 18 19 /** padding to 128 bytes, reserved for future use */ 20 uint32_t reserved[32-7]; 21 } hw_module_t;其中比較關鍵的是第 15 行 的 struct hw_module_methods_t* methods; hw_module_methods_t 的
定義如下
01 typedef struct hw_module_methods_t { 02 /** Open a specific device */ 03 int (*open)(const struct hw_module_t* module, const char* id, 04 struct hw_device_t** device); 05 06 } hw_module_methods_t;只有一個叫做 open 的函式指標, 此函式指標會對應到 Gralloc.cpp 中的 gralloc_device_open()函式.
2.調用 framebuffer_open(module, &fbDev) 以及 gralloc_open(module, &grDev)
調用完 hw_get_module() 之後, FramebufferNativeWindow 建構式接下來會分別調用framebuffer_open(module, &fbDev) 以及 gralloc_open(module, &grDev): 這兩個函式定義在
/hardware/libhardware/include/hardware/Gralloc.h, 以下是程式片段:
01 // framebuffer_open 02 static inline int framebuffer_open(const struct hw_module_t* module, 03 struct framebuffer_device_t** device) { 04 return module->methods->open(module, 05 GRALLOC_HARDWARE_FB0, (struct hw_device_t**)device); 06 } 07 // gralloc_open 08 static inline int gralloc_open(const struct hw_module_t* module, 09 struct alloc_device_t** device) { 10 return module->methods->open(module, 11 GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device); 12 }參數 GRALLOC_HARDWARE_FB0 以及 GRALLOC_HARDWARE_GPU0 定義在 Gralloc.h:
01 #define GRALLOC_HARDWARE_FB0 "fb0" 02 #define GRALLOC_HARDWARE_GPU0 "gpu0"從定義中看出兩者都會調用同一個函式 open(),但是傳入open()的第二個參數不同, 前
面提到過 open 是函式指標且對應Gralloc.cpp 中的gralloc_device_open(), 因此調
用 open() 其實是調用到gralloc_device_open():
01 int gralloc_device_open(const hw_module_t* module, const char* name, 02 hw_device_t** device) 03 { 04 int status = -EINVAL; 05 if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) { 06 gralloc_context_t *dev; 07 dev = (gralloc_context_t*)malloc(sizeof(*dev)); 08 09 /* initialize our state here */ 10 memset(dev, 0, sizeof(*dev)); 11 12 /* initialize the procs */ 13 dev->device.common.tag = HARDWARE_DEVICE_TAG; 14 dev->device.common.version = 0; 15 dev->device.common.module = const_cast<hw_module_t*>(module); 16 dev->device.common.close = gralloc_close; 17 18 dev->device.alloc = gralloc_alloc; 19 dev->device.free = gralloc_free; 20 21 *device = &dev->device.common; 22 status = 0; 23 } else { 24 status = fb_device_open(module, name, device); 25 } 26 return status; 27 28 }gralloc_open(module, &grDev) 調用 gralloc_device_open時
第二個參數傳入的是GRALLOC_HARDWARE_GPU0, 此時 gralloc_device_open()的
任務是填充結構體grDev. 以及18,19 行的函式指標 int(*alloc)對應到 gralloc_alloc()以
及 int(*free) 對應到 gralloc_free(). gralloc_open() 第二個參數 grDev 是 alloc_device_t 結構體
01 typedef struct alloc_device_t { 02 struct hw_device_t common; 03 int (*alloc)(struct alloc_device_t* dev, 04 int w, int h, int format, int usage, 05 buffer_handle_t* handle, int* stride); 06 int (*free)(struct alloc_device_t* dev, 07 buffer_handle_t handle); 08 09 } alloc_device_t;
framebuffer_open(module, &fbDev) 調用 gralloc_device_open時第二個參數傳入
GRALLOC_HARDWARE_FB0, 因此gralloc_device_open()會調用 fb_device_open(),
fb_device_open()除了填充結構體fbDev之外, 會調用 mapFrameBuffer() , mapFrameBuffer()會再調
用 mapFrameBufferLocked().
mapFrameBufferLocked()定義在 /hardware/libhardware/modules/gralloc/Framebuffer.cpp, 此函式會開
啟 framebuffer device, 並且調用 ioctl取得 framebuffer device的資訊.
參考 mapFrameBufferLocked() 函式片段如下:
01 // already initialized... 02 if (module->framebuffer) { 03 return 0; 04 } 05 char const * const device_template[] = { 06 "/dev/graphics/fb%u", 07 "/dev/fb%u", 08 0 }; 09 10 int fd = -1; 11 int i=0; 12 char name[64]; 13 14 while ((fd==-1) && device_template[i]) { 15 snprintf(name, 64, device_template[i], 0); 16 fd = open(name, O_RDWR, 0); //¶}±Ò framebuffer device 17 i++; 18 } 19 if (fd < 0) 20 return -errno; 21 22 struct fb_fix_screeninfo finfo; 23 if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) 24 return -errno; 25 26 struct fb_var_screeninfo info; 27 if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) 28 return -errno;比較關鍵的是 mapFrameBufferLocked() 以 page alignment計算出 framebuffer 的大小, 並透過
mmap()獲取 framebuffer的 virtual address. 程式片段如下:
01 int err; 02 size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres_virtual); //page 03 alignment 04 module->framebuffer = new private_handle_t(dup(fd), fbSize, 0); 05 06 module->numBuffers = info.yres_virtual / info.yres; 07 module->bufferMask = 0; 08 09 void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 10 if (vaddr == MAP_FAILED) { 11 LOGE("Error mapping the framebuffer (%s)", strerror(errno)); 12 return -errno; 13 } 14 module->framebuffer->base = intptr_t(vaddr); 15 module->framebuffer->phys_base = finfo.smem_start ; 16 LOGI("framebuffer->base=%x\n", module->framebuffer->base ); 17 LOGI("framebuffer->phys_base=%x\n", module->framebuffer->phys_base ); 18 memset(vaddr, 0, fbSize); 19 return 0;
3.FramebufferNativeWindow 物件建構式調用 gralloc_alloc()函式 配置 framebuffer:
Android 2.2 使用 double-buffer, 這部份的程式片段如下:01 mNumBuffers = 2; 02 mNumFreeBuffers = 2; 03 mBufferHead = mNumBuffers-1; 04 buffers[0] = new NativeBuffer( fbDev->width, fbDev->height, 05 fbDev->format, GRALLOC_USAGE_HW_FB); 06 buffers[1] = new NativeBuffer( fbDev->width, fbDev->height, 07 fbDev->format, GRALLOC_USAGE_HW_FB); 08 ¡@ 09 err = grDev->alloc(grDev, fbDev->width, fbDev->height, fbDev->format, 10 GRALLOC_USAGE_HW_FB, &buffers[0]->handle, 11 &buffers[0]->stride); //調用 gralloc_alloc 函式 12 13 LOGE_IF(err, "fb buffer 0 allocation failed w=%d, h=%d, err=%s", 14 fbDev->width, fbDev->height, strerror(-err)); 15 16 err = grDev->alloc(grDev, fbDev->width, fbDev->height, fbDev->format, 17 GRALLOC_USAGE_HW_FB, &buffers[1]->handle, 18 &buffers[1]->stride); //調用 gralloc_alloc 函式 19 20 21 LOGE_IF(err, "fb buffer 1 allocation failed w=%d, h=%d, err=%s", 22 fbDev->width, fbDev->height, strerror(-err));
Erzurum
回覆刪除istanbul
Ağrı
Malatya
Trabzon
AE45
kırıkkale evden eve nakliyat
回覆刪除amasya evden eve nakliyat
kayseri evden eve nakliyat
istanbul evden eve nakliyat
sakarya evden eve nakliyat
6UHF
adana evden eve nakliyat
回覆刪除bolu evden eve nakliyat
diyarbakır evden eve nakliyat
sinop evden eve nakliyat
kilis evden eve nakliyat
5DZ
8A726
回覆刪除Sinop Şehirler Arası Nakliyat
Çerkezköy Bulaşık Makinesi Tamircisi
Siirt Evden Eve Nakliyat
Coinex Güvenilir mi
Yobit Güvenilir mi
Artvin Lojistik
Hatay Şehir İçi Nakliyat
Maraş Şehirler Arası Nakliyat
Çerkezköy Motor Ustası
C0ECD
回覆刪除%20 komisyon indirimi
0E41D
回覆刪除Kadınlarla Ücretsiz Sohbet
sesli sohbet mobil
konya telefonda görüntülü sohbet
denizli rastgele görüntülü sohbet uygulamaları
aksaray en iyi ücretsiz görüntülü sohbet siteleri
canlı sohbet siteleri ücretsiz
sakarya bedava sohbet siteleri
canlı görüntülü sohbet siteleri
mersin rastgele sohbet uygulaması
51A67
回覆刪除kocaeli sesli sohbet
canli goruntulu sohbet siteleri
sohbet odaları
kayseri tamamen ücretsiz sohbet siteleri
düzce sesli sohbet siteleri
Uşak Muhabbet Sohbet
en iyi ücretsiz sohbet uygulamaları
Ardahan Canlı Sohbet Bedava
Tunceli Sesli Sohbet Sitesi
56134
回覆刪除Kripto Para Oynama
Görüntülü Sohbet Parasız
Kripto Para Nasıl Alınır
Twitter Takipçi Hilesi
Referans Kimliği Nedir
Cate Coin Hangi Borsada
Parasız Görüntülü Sohbet
Anc Coin Hangi Borsada
Tumblr Takipçi Satın Al
FB2BA
回覆刪除Binance Referans Kodu
Shibanomi Coin Hangi Borsada
Threads Yeniden Paylaş Hilesi
Soundcloud Beğeni Satın Al
Vector Coin Hangi Borsada
Periscope Beğeni Hilesi
Xcn Coin Hangi Borsada
Linkedin Takipçi Hilesi
Onlyfans Takipçi Hilesi
303BA
回覆刪除DefiLlama
thorchain
quickswap
shapeshift
uniswap
sushiswap
dappradar
pancakeswap
satoshivm
80980A04B9
回覆刪除tiktok takipçi