Android系统Surface机制的SurfaceFlinger服务的启动过程分析Word文档格式.docx
- 文档编号:22978258
- 上传时间:2023-02-06
- 格式:DOCX
- 页数:17
- 大小:21.74KB
Android系统Surface机制的SurfaceFlinger服务的启动过程分析Word文档格式.docx
《Android系统Surface机制的SurfaceFlinger服务的启动过程分析Word文档格式.docx》由会员分享,可在线阅读,更多相关《Android系统Surface机制的SurfaceFlinger服务的启动过程分析Word文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
main(String[]
args)
System.loadLibrary("
android_servers"
);
init1(args);
}
这个函数定义在文件
frameworks/base/services/java/com/android/server/SystemServer.java
中。
首先将
android_servers
库加载到
进
程中来,接着调用另外一个静态成员函数
init1
来启动
那些使用
C++语言来实现的系统服务。
是一个
JNI
方法,它是由
C++层的函数
android_server_SystemServer_init1
来实现的,接下来我
们就继续分析它的实现。
2.
SystemServer.init1
[cpp]
android_server_SystemServer_init1(JNIEnv*
env,
jobject
clazz)
system_init();
frameworks/base/services/jni/com_android_server_SystemServer.cpp
调用另外一个函数
system_init
来启动那些使
用
C++语言来实现的系统服务,它的实现在文件
frameworks/base/cmds/system_server/library/system_init.cpp
中,如下所示:
extern
"
C"
status_t
system_init()
LOGI("
Entered
system_init()"
sp<
ProcessState>
proc(ProcessState:
:
self());
char
propBuf[PROPERTY_VALUE_MAX];
property_get("
system_init.startsurfaceflinger"
propBuf,
1"
if
(strcmp(propBuf,
)
==
0)
//
Start
the
SurfaceFlinger
SurfaceFlinger:
instantiate();
(proc->
supportsProcesses())
server:
entering
thread
pool.\n"
ProcessState:
self()->
startThreadPool();
IPCThreadState:
joinThreadPool();
exiting
return
NO_ERROR;
函数首先获得
进程中的一个
ProcessState
单例,并且保存在变量
proc
中,
后面会通过调用它的成员函数
supportsProcesses
来判
断系统是否支持
Binder
进程间通信机制。
我们知道,在
系统中,每一个需要使用
进程间通信机制的进程内部都有一个
单例,它是用来和
驱动程序建立连接的,具体可以参考
系统进
程间通信(IPC)机制
中的
Server
启动过程源
代码分析一文。
函数接下来就检查系统中是否存在一个名称为“system_init.startsurfaceflinger”的
属性。
如果存在的话,就将它的值获取回来,
并且保存在缓冲区
proBuf
如果不存在的话,那么函数
property_get
就会将缓冲区
的值设置为“1”。
当缓冲区
的值等于“1”
的时候,就表示需要在
进程中将
服务启动起来,这是通过调用
instantiate
来实现的。
函数最后检查系统是否支持
如果支持的话,那么接下来
就会调用当前进程中的
单例的成员函数
startThreadPool
来启动一个
线程池,并且调用当前线程中的
IPCThreadState
单例来
将当前线程加入到前面所启动的
线程池中去。
从前面和两篇文章可以知道,System
进程前面在初
始化运行时库的过程中,已经调用过当前进程中的
来启动
线程池了,因此,这里其实只是
将当前线程加入到这个
有了这个
线程池之后,SurfaceFlinger
服务在启动完成之后,就可以为系统中的其他组件或
者进程提供服务了。
假设系统存在一个名称为“system_init.startsurfaceflinger”的属性,并且它的值等
于“1”,接下来我们就继续分析
的实现,以便可以了解
服务的启
动过程。
由于
类的静态成员函数
是从父类
BinderService
继承下来的,因此,接下来我们要分析的实际上是
的实现。
3.
BinderService.instantiate
template<
typename
SERVICE>
BinderService
public:
instantiate()
{
publish();
};
这个函数定义在文件
frameworks/base/include/binder/BinderService.h
的实现很简单,它只是调用
类的另外一个静态成员函数
publish
来继续执行
启动
服务的操作。
4.
BinderService.publish
publish()
IServiceManager>
sm(defaultServiceManager());
sm->
addService(String16(SERVICE:
getServiceName()),
new
SERVICE());
是一个模板类,它有一个模板参数
SERVICE。
当
类被
类继承时,模板参数
SERVICE
的值就等
于
SurfaceFlinger。
因此,BinderService
所执行的操作就是创建
一个
实例,用来作为系统的
服务,并且将这个服务注册到
Service
Manager
中去,这样系统中的其它组件
或者进程就可以通过
来获得
服务的
代理对象,进而使用它所提供的服务。
进程间通信机制
中的服务对象的注册过程可以参考
系统进程
间通信(IPC)机制
启动过程源代码分析一文。
接下来,我们就继续分析
服务的创建过程。
5.
SurfaceFlinger()
BnSurfaceComposer(),
Thread(false),
init();
frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp
从前面一文可以知道,SurfaceFlinger
类继承了
BnSurfaceComposer
类,而后者是一个实现了
ISurfaceComposer
接口的
本地对象类。
此外,SurfaceFlinger
类还继承了
Thread
类,后者是
用来创建一个线程的,这个线程就是我们在一文中提到的
UI
渲染线程,它
的线程执行体函数为
类的成员函数
threadLoop。
后面在分析
服务渲染
的过程时,我们再分析
threadLoop
注意,在初始化
的父类
时,传进
去的参数为
false,表示先不要将
服务
的
渲染线程启动起来,等到后面再启动。
服务在创建的过程中,会调用
init
来执
行初始化的操作,接下来,我们就继续分析它的实
现。
6.
SurfaceFlinger.init
init()
is
starting"
debugging
stuff...
value[PROPERTY_VALUE_MAX];
debug.sf.showupdates"
value,
0"
mDebugRegion
=
atoi(value);
debug.sf.showbackground"
mDebugBackground
LOGI_IF(mDebugRegion,"
showupdates
enabled"
LOGI_IF(mDebugBackground,"
showbackground
的实现很简单,它分别获得系统中两个名称为
“debug.sf.showupdates”和
“debug.sf.showbackground”的属性的值,并且分别保存在
类的成员变量
和
这两个成员变
量是与调试相关的,我们不关心。
这一步执行完成之后,返回到前面的
4
中,即
类的静态成员函
数
中,这时候在前面的
5
中所创建的一
个
实例就会被注册到
中,这是通过调用
的
代理对象的成员函数
addService
的第二个参数是一个类型为
IBinder
的强指针引用。
从前面一文可以知道,
当一个对象第一次被一个强指针引用时,那么这个对象的成员函数
onFirstRef
就会被调用。
因此,接下来前面所创建的
实例的
成员函数
就会被调用,以便可以继续执行初始化操作。
7.
SurfaceFlinger.onFirstRef
onFirstRef()
run("
SurfaceFlinger"
PRIORITY_URGENT_DISPLAY);
Wait
for
to
be
done
with
its
initialization
mReadyToRunBarrier.wait();
}<
span
style="
font-family:
Arial,
Helvetica,
sans-serif;
>
<
white-space:
normal;
/span>
函数首先调用从父类继承下来的成员函数
run
来启动一个名秒为“SurfaceFlinger”
的线程,用来执行
渲染操作。
这就是前面我们所
说的
渲染线程了。
这个
渲染线程创建完成之后,首先会调用
类的成
员函数
readyToRun
来执行一些初始化操作,接着再循环
调用
来作为线程的执行体。
mReadyToRunBarrier
是
类的一个成员变量,它的类型是
Barrier,用
来描述一个屏障,是通过条件变量来实现的。
我们
可以把它看作是一个线程同步工具,即阻塞当前线程,直到
渲染
线程执行完成初始化操作为止。
的实现,以便可
以了解
渲染线程的初始化过
程。
8.
SurfaceFlinger.oreadyToRun
文件
中,用来初始化
渲
染线程,我们分段来阅读:
readyToRun()
LOGI("
SurfaceFlinger'
s
ready
run.
Initializing
graphics
H/W..."
we
only
support
one
display
currently
int
dpy
0;
initialize
display
GraphicPlane&
plane(graphicPlane(dpy));
DisplayHardware*
const
hw
DisplayHardware(this,
dpy);
plane.setDisplayHardware(hw);
这段代码首先创建了一个
DisplayHardware
对象
hw,用来描述设备的显示屏,并
且用这个
对象来初始化
类的成员变量
mGraphicPlanes
所描述的一个
GraphicPlane
数组的第一个元素。
的创建过程中,会创建
另外一个线程,用来监控控制台事件,即监控硬件帧缓冲区的睡眠和唤醒事件。
在后面一
篇文章中介绍
服务是如何管理硬件帧
缓冲区时,我们就会看到这个控制台事件监控线程的创建过程。
我们接着往下阅读代码:
create
shared
control-block
mServerHeap
MemoryHeapBase(4096,
MemoryHeapBase:
READ_ONLY,
read-only
heap"
LOGE_IF(mServerHeap==0,
can'
t
memory
dealer"
mServerCblk
static_cast<
surface_flinger_cblk_t*>
(mServerHeap->
getBase());
LOGE_IF(mServerCblk==0,
get
control
block'
address"
new(mServerCblk)
surface_flinger_cblk_t;
这段代码首先创建了一块大小为
4096,即
4KB
的匿名共享内存,接着将这块匿名
共享内存结构化为一个
surface_flinger_cblk_t
对象来
访问。
对象就保存在
mServerCblk
这块匿名共享内存用来保存设备显示屏的属性信息,例如,宽度、高度、密度和每
秒多少帧等信息,后面我们就会看到这块匿名共享内
存的初始化过程。
为什么会使用匿名共享内存来保存设备显示屏的属性信息呢?
这是为了
方便将这些信息传递给系统中的其它进程访问的。
系
统中的其它进程可以通过调用调用
服务的代理对象的成员函数
getCblk
来获
得这块匿名共享内存的内容。
我们再接着往下阅读代码:
primary
reen
(other
should
initialized
in
same
manner,
but
asynchronously,
as
they
could
come
and
go.
None
of
this
supported
yet).
DisplayHardware&
plane.displayHardware();
uint32_t
w
hw.getWidth();
h
hw.getHeight();
f
hw.getFormat();
hw.makeCurrent();
这段代码首先获得
所描述的一个
数组的第一个元素
plane,接着再设置它的
宽度、长度和像素格式等作息,最后再调用它里面的一个
的成员
函数
makeCurrent
来将它作为系统的主显示屏。
这个
是在前面第一段代码中创建的,在创建的过程中,它会执行一些
初始化操作,这里将它设置为系统主显示屏之后,后面
就可以将系统的
渲染在它上面了。
在后面一篇文章中介绍
服务是如何管
理硬件帧缓冲区时,我们再分析
类的
我们继续往下阅读代码:
block
mServerCblk->
connected
|=
1<
dpy;
display_cblk_t*
dcblk
displays
+
memset(dcblk,
0,
sizeof(dis
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android 系统 Surface 机制 SurfaceFlinger 服务 启动 过程 分析
链接地址:https://www.bdocx.com/doc/22978258.html