SurfaceFliger绘制流程-CSDN博客
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
当HWComposer接收到Vsync信号时唤醒DisSync线程在其中唤醒EventThread线程调用DisplayEventReceiver的sendObjects像BitTub发送消息由于在SurfaceFlinger的init过程中创建了EventThread线程并添加到MQ中进行创建Connection并监听对应的BitTube信息因此最后会在MQ中接收到通知调用Handler的发送消息到SF的主线程中SF的handlerMessage方法去处理该消息并执行对应的绘制流程。
SurfaceFliger绘制流程
第一步
回调每个图层onPreComposition方法
第一步preComposition中获取到所有参与绘制的layer图层信息并回调onPreComposition方法观察是否有图层发生变化通过方法返回值判断
【通过判断MQueuedFrames是否大于0代表图层发生变化在onFrameAvailable中会对这个字段+1】
SurfaceFlinger可以控制某些Layer不参与绘制过程比如需要将悬浮按钮图层隐藏。
如果有则向MQ中发送invalidata消息SurfaceFliger的MQ接收到之后会调用 handleMessageTransaction()方法和handleMessageInvalidate() 方法根据是否刷新调用signalRefresh方法。
代码部分
void SurfaceFlinger::preComposition()
{
bool needExtraInvalidate = false;
const LayerVector& layers(mDrawingState.layersSortedByZ);
const size_t count = layers.size();
for (size_t i=0 ; i<count ; i++) {
//回调每个图层onPreComposition方法
if (layers[i]->onPreComposition()) {
needExtraInvalidate = true;
}
}
//当存在图层有变化则发送invalidate消息
if (needExtraInvalidate) {
signalLayerUpdate();
}
}
//图层是否发生变化是通过mQueuedFrames字段确定
bool Layer::onPreComposition() {
mRefreshPending = false;
return mQueuedFrames > 0 || mSidebandStreamChanged;
}
当Layer可见时会调用onFrameAvailable方法对mQueuedFrames+1
代码部分
void Layer::onFrameAvailable(const BufferItem& item) {
{ // Autolock scope
Mutex::Autolock lock(mQueueItemLock);
if (item.mFrameNumber == 1) {
mLastFrameNumberReceived = 0;
}
while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
ms2ns(500));
}
mQueueItems.push_back(item);
android_atomic_inc(&mQueuedFrames); //加1操作
//唤醒所有pending的回调方法
mLastFrameNumberReceived = item.mFrameNumber;
mQueueItemCondition.broadcast();
}
//和上面一样的操作通知flinger图层发生更新
mFlinger->signalLayerUpdate();
}
handleMessageTransaction方法的主要工作
- 遍历所有Layer来执行其doTransaction方法
- 处理显示设备的改变
- 处理layers的改变
- 提交transaction并更新光标情况。
doTransaction工作
比较上次Layer的状态宽高和此次Layer的状态宽高判断Layer尺寸是否发生变化当尺寸发生变化时调整Surface的缓冲区大小并调用Layer的invalidate重新计算可见区域大小并接着同步当前Layer状态接着再更新光标情况
handleMessageInvalidate工作
获取所有的layer将更新的图层放入到layerWithQueuedFrames中接着取出调用各个图层的latchBuffer处理。
rebuildLayerStacks
获取每个显示屏中的所有可见图层列表计算每个图层的可见区域根据Z轴的深度把所有图层添加进来
重建所有显示屏的各个可见Layer并重新根据Z轴调整Layer图层的顺序
后续分析
setUpHWcomposer
将Layer添加到HWComposer中
doComposition
postComposition
HWComposer更新frameBuffer缓冲区通过转换后的屏幕坐标判断是局部区域更新还是整个屏幕都需要更新Display从缓冲区中取出数据进行显示