Android系统Su易做图ce机制的Su易做图ceFlinger服务渲染应用程序UI的过程分析
在前面的一系列文章中,我们学习了Android应用程序与Su易做图ceFlinger服务的关系,以及Su易做图ceFlinger服务的启动过程、初始化硬件帧缓冲区的过程、线程模型。Su易做图ceFlinger服务所做的一切都是为了给Android应用程序提服务的,即为Android应用程序渲染它们的UI。在本文中,我们就详细分析Su易做图ceFlinger服务渲染Android应用程序UI的过程。
从前面Android系统Su易做图ce制的Su易做图ceFlinger服务的线程模型分析一文可以知道,Su易做图ceFlinger服务是通过它的UI渲染线程来将应用程序的UI渲染到硬件帧缓冲区中去的,因此,接下来我们就通过分析Su易做图ceFlinger服务的UI渲染线程的执行过程来分应用程序UI的渲染过程,这个过程如图1所示。
图1 Su易做图ceFlinger服务渲染应用程序UI的示意图
从图1就可以看出,Su易做图ceFlinger服务的UI渲染线程的执行过程如下所示:
1. 调用Su易做图ceFlinger类的成员函数handleConsoleEvents来处理控制台事件。
2. 调用Su易做图ceFlinger类的成员函数handleTransaction来处理系统显示屏以及应用程序窗口的属性变化,例如大小、旋转方向变化等。
3. 调用Su易做图ceFlinger类的成员函数handlePageFlip来让各个应用程序窗口设置它们当前所要渲染的图形缓冲区。
4. 如果Su易做图ceFlinger服务在编译的时候指定了USE_COMPOSITION_BYPASS宏,并且当前需要渲染的应用程序窗口只有一个,那么就会调用Su易做图ceFlinger类的成员函数handleBypassLayer来直接将这个应用程序窗口的图形缓冲区渲染到硬件帧缓冲区中去,否则的话,就要调用Su易做图ceFlinger类的成员函数handleRepaint来合成所有的应用程序窗口的图形缓冲区到一个主图形缓冲区中去。
5. 调用Su易做图ceFlinger类的成员函数postFramebuffer将前面得到的主图形缓冲区渲染到硬件帧缓冲区中去。
前面Android系统Su易做图ce制的Su易做图ceFlinger服务的线程模型分析一文中,我们已经分析过第1步的实现了,而通过前面Android应用程序与Su易做图ceFlinger服务的关系概述和学习计划这一系列文章的学习,我们也已经了解了应用程序窗口的图形缓冲区的创建过程,因此,接下来我们就在这些知识的基础上来详细分析第2步到第5的实现,即分别分析Su易做图ceFlinger类的成员函数handleTransaction、handlePageFlip、handleBypassLayer和postFramebuffer的实现。
1. handleTransaction
Su易做图ceFlinger类的成员函数handleTransaction是用来处理系统显示屏以及应用程序窗口的属性变化的,这个过程如图2所示。
图2 系统显示屏以及应用程序窗口的属性变化处理过程
这个过程可以分为6个步骤,接下来我们就详细分析每一个步骤。
Step 1. Su易做图ceFlinger.handleTransaction
[cpp]
void Su易做图ceFlinger::handleTransaction(uint32_t transactionFlags)
{
Vector< sp<LayerBase> > ditchedLayers;
/*
* Perform and commit the transaction
*/
{ // scope for the lock
Mutex::Autolock _l(mStateLock);
const nsecs_t now = systemTime();
mDebugInTransaction = now;
handleTransactionLocked(transactionFlags, ditchedLayers);
mLastTransactionTime = systemTime() - now;
mDebugInTransaction = 0;
// here the transaction has been committed
}
/*
* Clean-up all layers that went away
* (do this without the lock held)
*/
const size_t count = ditchedLayers.size();
for (size_t i=0 ; i<count ; i++) {
if (ditchedLayers[i] != 0) {
//LOGD("ditching layer %p", ditchedLayers[i].get());
ditchedLayers[i]->ditch();
}
}
}
这个函数定义在文件frameworks/base/services/su易做图ceflinger/Su易做图ceFlinger.cpp中。
Su易做图ceFlinger类的成员函数handleTransaction是通过调用另外一个成员函数handleTransactionLocked来处理系统显示屏以及应用程序窗口的属性变化的,而Su易做图ceFlinger类的成员函数handleTransactionLocked在处理完成系统显示屏以及应用程序窗口的属性变化之后,会返回系统中那些已经销毁了的应用程序窗口。
从Android应用程序与Su易做图ceFlinger服务的关系概述和学习计划这一系列文章可以知道,在Su易做图ceFlinger服务这一侧,应用程序窗口一般是使用一个Layer对象来描述的,又由于Layer类是从LayerBase类继承下来的,因此,我们可以那些已经销毁了的应用程序窗口保存在一个类型为sp<LayerBase>的向量ditchedLayers中。
Su易做图ceFlinger类的成员函数handleTransaction最后就调用保存在向量ditchedLayers中的每一个LayerBase对象的成员函数dtich来执行被销毁的应用程序窗口的清理操作,接下来我们就继续分析Su易做图ceFlinger类的成员函数handleTransactionLocked,看看它是如何处理系统显示屏以及应用程序窗口的属性变化的。
Step 2. Su易做图ceFlinger.handleTransactionLocked
Su易做图ceFlinger类的成员函数handleTransactionLocked定义在文件rameworks/base/services/su易做图ceflinger/Su易做图ceFlinger.cpp中,我们分三段来阅读:
[cpp]
void Su易做图ceFlinger::handleTransactionLocked(
uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
{
const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
const size_t count = currentLayers.size();
/*
* Traversal of the children
* (perform the transaction for each of them if needed)
*/
const bool 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;
const uint32_t flags = layer->doTransaction(0);
if (flags & Layer::eVisibleRegion)
mVisibleRegionsDirty = true;
}
}
这段代码用来处理应用程序窗口的属性变化
补充:移动开发 , Android ,