【Android GUI】从总体上了解Android的GUI体系

文章目录

  • 概览
    • Android硬件接口HAL
    • Gralloc与Framebuffer
  • Gralloc模块的加载
  • Gralloc提供的接口
  • Android原生的Gralloc实现
    • 打开framebuffer设备
    • 打开gralloc设备
  • 参考

概览

在这里插入图片描述

  • Linux内核提供了统一的framebuffer显示驱动。设备节点/dev/graphics/fb*或者/dev/fb*,其中fb0表示第一个Monitor。

  • Android的HAL层提供了Gralloc,包括fb和gralloc两个设备。fb负责打开内核的framebuffer、初始化配置。gralloc管理帧缓冲区的分配和释放。所以上层只需要通过Gralloc来间接访问帧缓冲区,来保证对framebuffer的统一管理。

  • HAL层的composer为UI合成提供接口,被surface flinger调用。

  • VSync是“Project Butter”加入的同步机制,可以通过硬件产生,也可以通过软件,即VSyncThread模拟。

  • OpenGL ES 是一个通用函数库,需要和具体平台建立关联才可以工作。

  • FramebufferNativeWindow负责OpenGL ES在Android平台本地化的中介之一

  • EGL为OpenGL ES配置本地窗口。

Android硬件接口HAL

HAL是Android很多子系统,例如显示系统、音频系统等和Linux kernel驱动之间通信的统一接口。

Gralloc与Framebuffer

Framebuffer是内核系统提供的图形硬件的抽象描述,它占用了系统存储空间的一部分,是一块包含屏幕显示信息的缓冲区。
Android中,Framebuffer提供的设备文件节点是/dev/graphics/fb*

Android的显示系统借助于HAL层的Gralloc操作帧缓冲区。

Gralloc模块的加载

Gralloc对应的模块是由FramebufferNativeWindow在构造函数中加载的。

hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
#define GRALLOC_HARDWARE_MODULE_ID "gralloc"

hw_get_module查找和ID值匹配的库:

#define HAL_LIBRARY_PATH1 "/system/lib/hw"
#define HAL_LIBRARY_PATH2 "/vendor/lib/hw"

lib库的命名形式:

gralloc.[ro.hardware].so
gralloc.[ro.product.board].so
gralloc.[ro.board.platform].so
gralloc.[ro.arch].so

默认的:

    gralloc.default.so

Gralloc提供的接口

/*hardware/libhardware/include/hardware/Hardware.h*/
typedef struct hw_module_t {struct hw_module_methods_t* methods;//一个HAL库必须提供的方法} hw_module_t;typedef struct hw_module_methods_t {int (*open)(const struct hw_module_t* module, const char* id,struct hw_device_t** device);
} hw_module_methods_t;

前面提供的架构图中,open接口可以帮助上层打开“fb0”和“gpu0”。fb0就是主屏幕,gpu0负责图形缓冲区的分配和释放。

/*frameworks/native/libs/ui/FramebufferNativeWindow.cpp*/
FramebufferNativeWindow::FramebufferNativeWindow()
: BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false)
{…err = framebuffer_open(module, &fbDev); //打开fb设备err = gralloc_open(module, &grDev);//打开gralloc设备

Android原生的Gralloc实现

Android原生态的Gralloc实现在hardware/libhardware/modules/gralloc中,它open接口对应的是:

/*hardware/libhardware/modules/gralloc/Gralloc.cpp*/
int gralloc_device_open(const hw_module_t* module, const char* name, hw_device_t** device)
{int status = -EINVAL;if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {//打开gralloc设备} else {status = fb_device_open(module, name, device);//否则就是fb设备}return status;
}

打开framebuffer设备

/*hardware/libhardware/modules/gralloc/Framebuffer.cpp*/
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)) {//设备名是否正确fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));/分配hw_device_t空间,   这是一个“壳”*/memset(dev, 0, sizeof(*dev));//初始化,良好的编程习惯…dev->device.common.close = fb_close;//这几个接口是fb设备的核心dev->device.setSwapInterval = fb_setSwapInterval;dev->device.post = fb_post;…private_module_t* m = (private_module_t*)module;status = mapFrameBuffer(m);//内存映射,以及参数配置if (status >= 0) {*device = &dev->device.common;//“壳”和“核心”的关系}}return status;
}

标准的fb设备需要实现:int (*post)(struct framebuffer_device_t* dev, buffer_handle_t buffer);,将buffer数据post到屏幕上 ,这样buffer内容在下一次VSYNC中被显示出来。
设置缓冲区swap的时间间隔:int (*setSwapInterval)(struct framebuffer_device_t* window, int interval);
设置刷新区域:int (*setUpdateRect)(struct framebuffer_device_t* window, int left, int top, int width, int height);

接着是打开kernel层的fb设备和对fb进行配置,在mapFrameBuffer()中完成,它会尝试打开:

"/dev/graphics/fb%u"或者 "/dev/fb%u"

打开后,通过

ioctl(fd, FBIOGET_FSCREENINFO, &finfo);
ioctl(fd, FBIOGET_VSCREENINFO, &info)

得到屏幕参数,接着通过ioctl(fd, FBIOPUT_VSCREENINFO, &info)对fb进行配置。

mapFrameBuffer()的另外一个任务是做为fb设备做内存映射:

    void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);    module->framebuffer->base = intptr_t(vaddr);memset(vaddr, 0, fbSize);

打开gralloc设备

/*hardware/libhardware/modules/gralloc/Gralloc.cpp*/
int gralloc_device_open(const hw_module_t* module, const char* name, hw_device_t** device)
{int status = -EINVAL;if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {gralloc_context_t *dev;//做法和fb类似dev = (gralloc_context_t*)malloc(sizeof(*dev));//分配空间/* initialize our state here */memset(dev, 0, sizeof(*dev));…dev->device.alloc = gralloc_alloc; //从提供的接口来看,gralloc主要负责“分配和释放”操作dev->device.free = gralloc_free;}

总结下Android原生的Gralloc:
在这里插入图片描述

参考

《深入理解Android内核设计思想》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/824645.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速上手Linux核心命令

Linux 的重要性不用我多说了吧,大多数互联网公司,服务器都是采用的Linux操作系统 Linux是一个主要通过命令行来进行管理的操作系统。 只有熟练掌握Linux核心命令,在使用起来我们才会得心应手 这里给大家整理了Linux一些核心命令&#xff0…

Android --- Activity

官方文档-activity Activity 提供窗口,供应在其中多个界面。此窗口通常会填满屏幕,但也可能小于屏幕并浮动在其他窗口之上。 大多数应用包含多个屏幕,这意味着它们包含多个 Activity。通常,应用中的一个 Activity 会被指定主 Ac…

JAVA基础08- 继承,重写,super以及this

目录 继承(extends) 定义 说明 作用 方法的重写 定义 重写关键点 方法重写与重载的区别 练习 练习1(方法继承与重写的简单练习) 练习2(方法继承与重写的进阶练习) This的使用 定义 作用以及注…

基于SpringBoot+Vue的IT技术交流平台(源码+文档+包运行)

一.系统概述 我国科学技术的不断发展,计算机的应用日渐成熟,其强大的功能给人们留下深刻的印象,它已经应用到了人类社会的各个层次的领域,发挥着重要的不可替换的作用。信息管理作为计算机应用的一部分,使用计算机进行…

leetcode-分割链表

题目 面试题 02.04. 分割链表 提示 给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你不需要 保留 每个分区中各节点的初始相对位置。 示例 1: 输入&#xff…

搜维尔科技:【工业仿真】煤矿安全知识基础学习VR系统

产品概述 煤矿安全知识基础学习VR系统 系统内容: 煤矿安全知识基础学习VR系统内容包括:下井流程(正确乘坐罐笼、班前会、井下行走注意事项、工作服穿戴、入井检身及人员清点、下井前准备工作、提升运输安全);运煤流程…

SpringBoot集成RockerMQ

1.引入依赖 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.2.0</version> </dependency>2.配置服务器地址 #Rocketmq配置 rocketmq.name-server192…

专业清洁工匠服务网站模板 html网站

目录 一.前言 二.页面展示 三.下载链接 一.前言 该HTML代码生成了一个网页&#xff0c;包括以下内容&#xff1a; 头部信息&#xff1a;指定了网页的基本设置和元数据&#xff0c;例如字符编码、视口大小等。CSS文件&#xff1a;引入了多个CSS文件&#xff0c;用于设置网页…

EI级 | Matlab实现VMD-TCN-LSTM-MATT变分模态分解卷积长短期记忆神经网多头注意力多变量时间序列预测

EI级 | Matlab实现VMD-TCN-LSTM-MATT变分模态分解卷积长短期记忆神经网多头注意力多变量时间序列预测 目录 EI级 | Matlab实现VMD-TCN-LSTM-MATT变分模态分解卷积长短期记忆神经网多头注意力多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实…

动手写sql 《牛客网80道sql》

第1章&#xff1a;SQL编写基础逻辑和常见问题 基础逻辑 SELECT语句: 选择数据表中的列。FROM语句: 指定查询将要从哪个表中检索数据。WHERE语句: 过滤条件&#xff0c;用于提取满足特定条件的记录。GROUP BY语句: 对结果进行分组。HAVING语句: 对分组后的结果进行条件过滤。O…

【STM32】嵌入式实验二 GPIO 实验 (前三个设计)

1&#xff0e; 按键亮灯 设计 GPIO 实验项目 1&#xff0c;功能&#xff1a;当按键 KB1 按下时&#xff0c;实验板上全彩发光二极管周边 的发光二极管全亮&#xff0c;当按键 KB2 按下时跑马灯 D0 闪亮。 实验要求基于寄存器的GPIO配置&#xff0c;所以需要手动操作寄存器来配…

联想小新Air14-2019锐龙版更换硬盘

首先打下D面所有螺丝&#xff08;内六角螺丝&#xff0c;需要准备螺丝刀&#xff09;&#xff0c;然后从下方翘起整个D面打开如下图 原装为2280长度的海力士硬盘&#xff0c;有空余的2242长度硬盘位 更换前断电&#xff0c;建议拆下电池&#xff08;扣下电池排线后不好安装&am…

每日OJ题_完全背包④_力扣279. 完全平方数(一维和二维)

目录 力扣279. 完全平方数 问题解析 解析代码 优化代码&#xff08;相同子问题分析和滚动数组&#xff09; 力扣279. 完全平方数 279. 完全平方数 难度 中等 给你一个整数 n &#xff0c;返回 和为 n 的完全平方数的最少数量 。 完全平方数 是一个整数&#xff0c;其值…

百科不全书之 docker记录

docker记录 1 参考文件2. Docker简介与虚拟机的区别 1 参考文件 参考视频&#xff1a;B站【GeekHour】30分钟Docker入门教程: link 2. Docker简介 Docker是一个用于构建运行 传送 应用程序的平台。 与虚拟机的区别 虚拟机使用了一种叫做虚拟化的技术。每台虚拟机需要占…

固定测斜仪:工程观测的精密利器

在工程观测测量领域&#xff0c;固定测斜仪扮演着至关重要的角色。固定测斜仪&#xff0c;凭借其耐冲击型倾斜传感器、出色的可靠性、快速稳定的特点&#xff0c;以及简洁的安装和智能识别功能&#xff0c;已成为行业内重要工具。其输出信号为RS485数字量&#xff0c;可直接显示…

使用electron打包vuecli创建的项目

下面是我打包的时候才过的所有的坑&#x1f4a3;&#xff1a; 首先创建一个vue2的空项目&#xff0c;如果全局安装的vue-cli版本太低&#xff0c;低于3就无法使用vue create命令&#xff0c;必须使用uninstall将之前的卸载掉&#xff0c;在重现安装&#xff0c;之后的就是最近…

握手问题(蓝桥杯)

文章目录 握手问题【问题描述】答案&#xff1a;1204解题思路模拟 握手问题 【问题描述】 小蓝组织了一场算法交流会议&#xff0c;总共有 50 人参加了本次会议。在会议上&#xff0c;大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进行一次握手&#…

Scrapy框架内存泄漏问题及解决

说明&#xff1a;仅供学习使用&#xff0c;请勿用于非法用途&#xff0c;若有侵权&#xff0c;请联系博主删除 作者&#xff1a;zhu6201976 一、问题背景及原因 官方文档&#xff1a;Debugging memory leaks — Scrapy 2.11.1 documentation Scrapy是一款功能强大的网络爬虫框…

SpringMVC 常用注解介绍

Spring MVC 常用注解介绍 文章目录 Spring MVC 常用注解介绍准备1. RequestMapping1.1 介绍2.2 注解使用 2. 请求参数2.1 传递单个参数2.2 传递多个参数2.3 传递对象2.4 传递数组 3. RequestParam3.1 注解使用3.2 传入集合 4. RequestBody5. PathVariable6. RequestPart7. Rest…

k8s使用harbor私有仓库镜像 —— 筑梦之路

官方文档: Secret | Kubernetes ImagePullSecrets的设置是kubernetes机制的另一亮点&#xff0c;习惯于直接使用Docker Pull来拉取公共镜像&#xff0c;但非所有容器镜像都是公开的。此外&#xff0c;并不是所有的镜像仓库都允许匿名拉取&#xff0c;也就是说需要身份认证&…