Transaction是“事务”的意思。在我脑海中,关于事务的知识来自于数据库。在数据库操作中,事务意味着一次可以提交多个SQL语句,然后一个commit就可让它们集中执行,而且数据库中的事务还可以回滚,即恢复到事务提交前的状态。
SurfaceFlinger为什么需要事务呢?从上面对数据库事务的描述来看,是不是意味着一次执行多个请求呢?如直接盯着SF的源码来分析,可能不太容易搞清楚事务的前因后果,我想还是用老办法,从一个例子入手吧。
在WindowManagerService.java中,有一个函数之前分析过,现在再看看,代码如下所示:
**WindowManagerService.java::WinState**
~~~
Surface createSurfaceLocked() {
Surface.openTransaction(); //开始一次transaction
try {
try {
mSurfaceX = mFrame.left + mXOffset;
mSurfaceY = mFrame.top + mYOffset;
//设置Surface的位置
mSurface.setPosition(mSurfaceX, mSurfaceY);
......
}
}finally {
Surface.closeTransaction(); //关闭这次事务
}
~~~
这个例子很好地展示了事务的调用流程,它会依次调用:
- openTransaction
- setPosition
- closeTransaction
下面就来分析这几个函数的调用。
1. openTransaction的分析
看JNI对应的函数,代码如下所示:
**android_View_Surface.cpp**
~~~
static void Surface_openTransaction(JNIEnv* env,jobject clazz)
{
//调用SurfaceComposerClient的openGlobalTransaction函数
SurfaceComposerClient::openGlobalTransaction();
}
~~~
下面转到SurfaceComposerClient,代码如下所示:
**SurfaceComposerClient.cpp**
~~~
voidSurfaceComposerClient::openGlobalTransaction()
{
Mutex::Autolock _l(gLock);
......
constsize_t N = gActiveConnections.size();
for(size_t i=0; i<N; i++) {
sp<SurfaceComposerClient>client(gActiveConnections.valueAt(i).promote());
//gOpenTransactions存储当前提交事务请求的Client
if(client != 0 && gOpenTransactions.indexOf(client) < 0) {
//Client是保存在全局变量gActiveConnections中的SurfaceComposerClient
//对象,调用它的openTransaction。
if (client->openTransaction() == NO_ERROR) {
if (gOpenTransactions.add(client) < 0) {
client->closeTransaction();
}
}
......
}
}
}
~~~
上面是一个静态函数,内部调用了各个SurfaceComposerClient对象的openTranscation,代码如下所示:
**SurfaceComposerClient.cpp**
~~~
status_tSurfaceComposerClient::openTransaction()
{
if(mStatus != NO_ERROR)
return mStatus;
Mutex::Autolock _l(mLock);
mTransactionOpen++; //一个计数值,用来控制事务的提交。
if(mPrebuiltLayerState == 0) {
mPrebuiltLayerState = new layer_state_t;
}
returnNO_ERROR;
}
~~~
layer_state_t是用来保存Surface的一些信息的,比如位置、宽、高等信息。实际上,调用的setPosition等函数,就是为了改变这个layer_state_t中的值。
2. setPosition的分析
上文说过,SFC中有一个layer_state_t对象用来保存Surface的各种信息。这里以setPosition为例,来看它的使用情况。这个函数是用来改变surface在屏幕上的位置的,代码如下所示:
**android_View_Surface.cpp**
~~~
static void Surface_setPosition(JNIEnv* env,jobject clazz, jint x, jint y)
{
constsp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
if(surface == 0) return;
status_t err = surface->setPosition(x, y);
}
~~~
**Surface.cpp**
~~~
status_t SurfaceControl::setPosition(int32_t x,int32_t y) {
constsp<SurfaceComposerClient>& client(mClient);
status_t err = validate();
if (err < 0) return err;
//调用SurfaceComposerClient的setPosition函数
returnclient->setPosition(mToken, x, y);
}
~~~
**SurfaceComposerClient.cpp**
~~~
status_tSurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y)
{
layer_state_t* s = _lockLayerState(id); //找到对应的layer_state_t
if(!s) return BAD_INDEX;
s->what |= ISurfaceComposer::ePositionChanged;
s->x = x;
s->y = y; //上面几句修改了这块layer的参数
_unlockLayerState(); //该函数将unlock一个同步对象,其他没有做什么工作
returnNO_ERROR;
}
~~~
setPosition就是修改了layer_state_t中的一些参数,那么,这个状态是什么时候传递到SurfaceFlinger中的呢?
3. 分析closeTransaction
相信读者此时已明白为什么叫“事务”了。原来,在openTransaction和closeTransaction中可以有很多操作,然后由closeTransaction一次性地把这些修改提交到SF上,来看代码:
**android_View_Surface.cpp**
~~~
static void Surface_closeTransaction(JNIEnv*env, jobject clazz)
{
SurfaceComposerClient::closeGlobalTransaction();
}
~~~
**SurfaceComposerClient.cpp**
~~~
voidSurfaceComposerClient::closeGlobalTransaction()
{
......
const size_t N = clients.size();
sp<ISurfaceComposer>sm(getComposerService());
//①先调用SF的openGlobalTransaction
sm->openGlobalTransaction();
for (size_t i=0; i<N; i++) {
//②然后调用每个SurfaceComposerClient对象的closeTransaction
clients[i]->closeTransaction();
}
//③最后调用SF的closeGlobalTransaction
sm->closeGlobalTransaction();
}
~~~
上面一共列出了三个函数,它们都是跨进程的调用,下面对其一一进行分析。
(1)SurfaceFlinger的openGlobalTransaction分析
这个函数其实很简单,略看就行了。
**SurfaceFlinger.cpp**
~~~
void SurfaceFlinger::openGlobalTransaction()
{
android_atomic_inc(&mTransactionCount);//又是一个计数控制
}
~~~
(2)SurfaceComposerClient的closeTransaction分析
代码如下所示:
**SurfaceComposerClient.cpp**
~~~
status_tSurfaceComposerClient::closeTransaction()
{
if(mStatus != NO_ERROR)
return mStatus;
Mutex::Autolock _l(mLock);
......
constssize_t count = mStates.size();
if (count) {
//mStates是这个SurfaceComposerClient中保存的所有layer_state_t数组,也就是
//每个Surface一个。然后调用跨进程的setState
mClient->setState(count, mStates.array());
mStates.clear();
}
returnNO_ERROR;
}
~~~
BClient的setState,最终会转到SF的setClientState上,代码如下所示:
**SurfaceFlinger.cpp**
~~~
status_t SurfaceFlinger::setClientState(ClientIDcid, int32_t count,
const layer_state_t*states)
{
Mutex::Autolock _l(mStateLock);
uint32_t flags = 0;
cid<<= 16;
for(int i=0 ; i<count ; i++) {
const layer_state_t& s = states[i];
sp<LayerBaseClient> layer(getLayerUser_l(s.surface | cid));
if(layer != 0) {
const uint32_t what = s.what;
if (what & ePositionChanged) {
if (layer->setPosition(s.x, s.y))
//eTraversalNeeded表示需要遍历所有显示层
flags |= eTraversalNeeded;
}
....
if(flags) {
setTransactionFlags(flags);//这里将会触发threadLoop的事件。
}
returnNO_ERROR;
}
~~~
**SurfaceFlinger.cpp**
~~~
uint32_tSurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay)
{
uint32_t old = android_atomic_or(flags, &mTransactionFlags);
if((old & flags)==0) {
if(delay > 0) {
signalDelayedEvent(delay);
}else {
signalEvent(); //设置完mTransactionFlags后,触发事件。
}
}
returnold;
}
~~~
(3)SurfaceFlinger的closeGlobalTransaction分析
来看代码:
**SurfaceFlinger.cpp**
~~~
void SurfaceFlinger::closeGlobalTransaction()
{
if (android_atomic_dec(&mTransactionCount) ==1) {
//注意下面语句的执行条件,当mTransactionCount变为零时才执行,这意味着
//openGlobalTransaction两次的话,只有最后一个closeGlobalTransaction调用
//才会真正地提交事务
signalEvent();
Mutex::Autolock _l(mStateLock);
//如果这次事务涉及尺寸调整,则需要等一段时间
while (mResizeTransationPending) {
status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
if (CC_UNLIKELY(err != NO_ERROR)) {
mResizeTransationPending = false;
break;
}
}
}
}
~~~
关于事务的目的,相信读者已经比较清楚了:
- 就是将一些控制操作(例如setPosition)的修改结果,一次性地传递给SF进行处理。
那么,哪些操作需要通过事务来传递呢?通过查看Surface.h可以知道,下面这些操作需要通过事务来传递(这里只列出了几个经常用的函数):setPosition、setAlpha、show/hide、setSize、setFlag等。
由于这些修改不像重绘那么简单,有时它会涉及其他的显示层,例如在显示层A的位置调整后,之前被A遮住的显示层B,现在可能变得可见了。对于这种情况,所提交的事务会设置eTraversalNeeded标志,这个标志表示要遍历所有显示层进行处理。关于这一点,来看工作线程中的事务处理。
4. 工作线程中的事务处理
还是从代码入手分析,如下所示:
**SurfaceFlinger.cpp**
~~~
bool SurfaceFlinger::threadLoop()
{
waitForEvent();
if(LIKELY(mTransactionCount == 0)) {
const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
uint32_ttransactionFlags = getTransactionFlags(mask);
if(LIKELY(transactionFlags)) {
handleTransaction(transactionFlags);
}
}
...
}
~~~
getTransactionFlags函数的实现蛮有意思,不妨看看其代码,如下所示:
**SurfaceFlinger.cpp**
~~~
uint32_t SurfaceFlinger::getTransactionFlags(uint32_tflags)
{
//先通过原子操作去掉mTransactionFlags中对应的位。
//而后原子操作返回的旧值和flags进行与操作
return android_atomic_and(~flags,&mTransactionFlags) & flags;
}
~~~
getTransactionFlags所做的工作不仅仅是get那么简单,它还设置了mTransactionFlags,从这个角度来看,getTransactionFlags这个名字有点名不副实。
接着来看最重要的handleTransaction函数,代码如下所示:
**SurfaceFlinger.cpp**
~~~
void SurfaceFlinger::handleTransaction(uint32_ttransactionFlags)
{
Vector< sp<LayerBase> > ditchedLayers;
{
Mutex::Autolock _l(mStateLock);
//调用handleTransactionLocked函数处理
handleTransactionLocked(transactionFlags, ditchedLayers);
}
constsize_t count = ditchedLayers.size();
for(size_t i=0 ; i<count ; i++) {
if(ditchedLayers[i] != 0) {
//ditch是丢弃的意思,有些显示层可能被hide了,所以这里做些收尾的工作
ditchedLayers[i]->ditch();
}
}
}
~~~
**SurfaceFlinger.cpp**
~~~
void SurfaceFlinger::handleTransactionLocked(
uint32_t transactionFlags, Vector< sp<LayerBase> >&ditchedLayers)
{
//这里使用了mCurrentState,它的layersSortedByZ数组存储了SF中所有的显示层
constLayerVector& currentLayers(mCurrentState.layersSortedByZ);
constsize_t count = currentLayers.size();
constbool layersNeedTransaction = transactionFlags & eTraversalNeeded;
//如果需要遍历所有显示的话。
if(layersNeedTransaction) {
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer = currentLayers[i];
uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
if (!trFlags) continue;
//调用各个显示层的doTransaction函数。
constuint32_t flags = layer->doTransaction(0);
if (flags & Layer::eVisibleRegion)
mVisibleRegionsDirty = true;
}
}
if(transactionFlags & eTransactionNeeded) {
if(mCurrentState.orientation != mDrawingState.orientation) {
//横竖屏如果发生切换,需要对应变换设置。
const int dpy = 0;
const int orientation = mCurrentState.orientation;
const uint32_t type = mCurrentState.orientationType;
GraphicPlane& plane(graphicPlane(dpy));
plane.setOrientation(orientation);
......
}
/*
mLayersRemoved变量在显示层被移除的时候设置,例如removeLayer函数,这些函数
也会触发handleTranscation函数的执行
*/
if(mLayersRemoved) {
mLayersRemoved = false;
mVisibleRegionsDirty = true;
const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
const size_t count = previousLayers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(previousLayers[i]);
if (currentLayers.indexOf( layer ) < 0) {
ditchedLayers.add(layer);
mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
}
}
}
free_resources_l();
}
//提交事务处理,有必要进去看看。
commitTransaction();
}
~~~
每个显示层对事务的具体处理,都在它们的doTranscation函数中,读者若有兴趣,可进去看看。需要说明的是,每个显示层内部也有一个状态变量,doTransaction会更新这些状态变量。
回到上面的函数,最后它将调用commitTransaction提交事务,代码如下所示:
**SurfaceFlinger.cpp**
~~~
void SurfaceFlinger::commitTransaction()
{
//mDrawingState将使用更新后的mCurrentState
mDrawingState = mCurrentState;
mResizeTransationPending = false;
//触发一个条件变量,这样等待在closeGlobalTransaction函数中的线程可以放心地返回了。
mTransactionCV.broadcast();
}
~~~
- 前言
- 第1章 阅读前的准备工作
- 1.1 系统架构
- 1.1.1 Android系统架构
- 1.1.2 本书的架构
- 1.2 搭建开发环境
- 1.2.1 下载源码
- 1.2.2 编译源码
- 1.3 工具介绍
- 1.3.1 Source Insight介绍
- 1.3.2 Busybox的使用
- 1.4 本章小结
- 第2章 深入理解JNI
- 2.1 JNI概述
- 2.2 学习JNI的实例:MediaScanner
- 2.3 Java层的MediaScanner分析
- 2.3.1 加载JNI库
- 2.3.2 Java的native函数和总结
- 2.4 JNI层MediaScanner的分析
- 2.4.1 注册JNI函数
- 2.4.2 数据类型转换
- 2.4.3 JNIEnv介绍
- 2.4.4 通过JNIEnv操作jobject
- 2.4.5 jstring介绍
- 2.4.6 JNI类型签名介绍
- 2.4.7 垃圾回收
- 2.4.8 JNI中的异常处理
- 2.5 本章小结
- 第3章 深入理解init
- 3.1 概述
- 3.2 init分析
- 3.2.1 解析配置文件
- 3.2.2 解析service
- 3.2.3 init控制service
- 3.2.4 属性服务
- 3.3 本章小结
- 第4章 深入理解zygote
- 4.1 概述
- 4.2 zygote分析
- 4.2.1 AppRuntime分析
- 4.2.2 Welcome to Java World
- 4.2.3 关于zygote的总结
- 4.3 SystemServer分析
- 4.3.1 SystemServer的诞生
- 4.3.2 SystemServer的重要使命
- 4.3.3 关于 SystemServer的总结
- 4.4 zygote的分裂
- 4.4.1 ActivityManagerService发送请求
- 4.4.2 有求必应之响应请求
- 4.4.3 关于zygote分裂的总结
- 4.5 拓展思考
- 4.5.1 虚拟机heapsize的限制
- 4.5.2 开机速度优化
- 4.5.3 Watchdog分析
- 4.6 本章小结
- 第5章 深入理解常见类
- 5.1 概述
- 5.2 以“三板斧”揭秘RefBase、sp和wp
- 5.2.1 第一板斧--初识影子对象
- 5.2.2 第二板斧--由弱生强
- 5.2.3 第三板斧--破解生死魔咒
- 5.2.4 轻量级的引用计数控制类LightRefBase
- 5.2.5 题外话-三板斧的来历
- 5.3 Thread类及常用同步类分析
- 5.3.1 一个变量引发的思考
- 5.3.2 常用同步类
- 5.4 Looper和Handler类分析
- 5.4.1 Looper类分析
- 5.4.2 Handler分析
- 5.4.3 Looper和Handler的同步关系
- 5.4.4 HandlerThread介绍
- 5.5 本章小结
- 第6章 深入理解Binder
- 6.1 概述
- 6.2 庖丁解MediaServer
- 6.2.1 MediaServer的入口函数
- 6.2.2 独一无二的ProcessState
- 6.2.3 时空穿越魔术-defaultServiceManager
- 6.2.4 注册MediaPlayerService
- 6.2.5 秋风扫落叶-StartThread Pool和join Thread Pool分析
- 6.2.6 你彻底明白了吗
- 6.3 服务总管ServiceManager
- 6.3.1 ServiceManager的原理
- 6.3.2 服务的注册
- 6.3.3 ServiceManager存在的意义
- 6.4 MediaPlayerService和它的Client
- 6.4.1 查询ServiceManager
- 6.4.2 子承父业
- 6.5 拓展思考
- 6.5.1 Binder和线程的关系
- 6.5.2 有人情味的讣告
- 6.5.3 匿名Service
- 6.6 学以致用
- 6.6.1 纯Native的Service
- 6.6.2 扶得起的“阿斗”(aidl)
- 6.7 本章小结
- 第7章 深入理解Audio系统
- 7.1 概述
- 7.2 AudioTrack的破解
- 7.2.1 用例介绍
- 7.2.2 AudioTrack(Java空间)分析
- 7.2.3 AudioTrack(Native空间)分析
- 7.2.4 关于AudioTrack的总结
- 7.3 AudioFlinger的破解
- 7.3.1 AudioFlinger的诞生
- 7.3.2 通过流程分析AudioFlinger
- 7.3.3 audio_track_cblk_t分析
- 7.3.4 关于AudioFlinger的总结
- 7.4 AudioPolicyService的破解
- 7.4.1 AudioPolicyService的创建
- 7.4.2 重回AudioTrack
- 7.4.3 声音路由切换实例分析
- 7.4.4 关于AudioPolicy的总结
- 7.5 拓展思考
- 7.5.1 DuplicatingThread破解
- 7.5.2 题外话
- 7.6 本章小结
- 第8章 深入理解Surface系统
- 8.1 概述
- 8.2 一个Activity的显示
- 8.2.1 Activity的创建
- 8.2.2 Activity的UI绘制
- 8.2.3 关于Activity的总结
- 8.3 初识Surface
- 8.3.1 和Surface有关的流程总结
- 8.3.2 Surface之乾坤大挪移
- 8.3.3 乾坤大挪移的JNI层分析
- 8.3.4 Surface和画图
- 8.3.5 初识Surface小结
- 8.4 深入分析Surface
- 8.4.1 与Surface相关的基础知识介绍
- 8.4.2 SurfaceComposerClient分析
- 8.4.3 SurfaceControl分析
- 8.4.4 writeToParcel和Surface对象的创建
- 8.4.5 lockCanvas和unlockCanvasAndPost分析
- 8.4.6 GraphicBuffer介绍
- 8.4.7 深入分析Surface的总结
- 8.5 SurfaceFlinger分析
- 8.5.1 SurfaceFlinger的诞生
- 8.5.2 SF工作线程分析
- 8.5.3 Transaction分析
- 8.5.4 关于SurfaceFlinger的总结
- 8.6 拓展思考
- 8.6.1 Surface系统的CB对象分析
- 8.6.2 ViewRoot的你问我答
- 8.6.3 LayerBuffer分析
- 8.7 本章小结
- 第9章 深入理解Vold和Rild
- 9.1 概述
- 9.2 Vold的原理与机制分析
- 9.2.1 Netlink和Uevent介绍
- 9.2.2 初识Vold
- 9.2.3 NetlinkManager模块分析
- 9.2.4 VolumeManager模块分析
- 9.2.5 CommandListener模块分析
- 9.2.6 Vold实例分析
- 9.2.7 关于Vold的总结
- 9.3 Rild的原理与机制分析
- 9.3.1 初识Rild
- 9.3.2 RIL_startEventLoop分析
- 9.3.3 RIL_Init分析
- 9.3.4 RIL_register分析
- 9.3.5 关于Rild main函数的总结
- 9.3.6 Rild实例分析
- 9.3.7 关于Rild的总结
- 9.4 拓展思考
- 9.4.1 嵌入式系统的存储知识介绍
- 9.4.2 Rild和Phone的改进探讨
- 9.5 本章小结
- 第10章 深入理解MediaScanner
- 10.1 概述
- 10.2 android.process.media分析
- 10.2.1 MSR模块分析
- 10.2.2 MSS模块分析
- 10.2.3 android.process.media媒体扫描工作的流程总结
- 10.3 MediaScanner分析
- 10.3.1 Java层分析
- 10.3.2 JNI层分析
- 10.3.3 PVMediaScanner分析
- 10.3.4 关于MediaScanner的总结
- 10.4 拓展思考
- 10.4.1 MediaScannerConnection介绍
- 10.4.2 我问你答
- 10.5 本章小结