当前位置: 首页 > news >正文

SurfaceFliger绘制流程

前景提要:

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从缓冲区中取出数据进行显示

原文链接:SurfaceFliger绘制流程 - 掘金 (juejin.cn)

http://www.lryc.cn/news/212923.html

相关文章:

  • 系统架构设计师-第14章-云原生架构设计理论与实践-
  • conda 实践
  • 行业追踪,2023-10-31
  • springboot 配置多个Redis数据源详解
  • 【数据结构】排序算法总结
  • 作为20年老程序员,我如何使用GPT4来帮我写代码
  • 【机器学习合集】模型设计之残差网络 ->(个人学习记录笔记)
  • GoLong的学习之路(十六)基础工具之Gin框架
  • VMware打开centos黑屏解决方法汇总
  • 5G物联网关相较有线网关有哪些独特优势
  • 【数据结构】顺序表的学习
  • 在NISQ小型计算机上执行大型并行量子计算的可能性
  • 考虑时空相关性的风电功率预测误差MATLAB代码
  • ASP.NET WebApi 极简依赖注入
  • 解决proteus仿真stm32,IIC通讯,IIC DEBUG无法显示从机应答信号的问题(问题情况为在8位数据后应答位显示?)
  • PHP判断闰年
  • 证照之星XE专业版下载专业证件照制作工具
  • VR全景图片如何制作?揭秘VR全景图片制作全流程
  • vue element el-table-column 循环示例代码
  • R语言生物群落(生态)数据统计分析与绘图实践技术应用
  • 有了 GPT,还需要付费咨询吗?
  • 如何搭建一台服务器?
  • [转载]C++序列化框架介绍和对比
  • 分类预测 | Matlab实现KOA-CNN-BiLSTM-selfAttention多特征分类预测(自注意力机制)
  • 浮点数和定点数(上):怎么用有限的Bit表示尽可能多的信息?
  • 一文详解汽车电子LIN总线
  • 论文阅读——GPT3
  • 星环科技分布式向量数据库Transwarp Hippo正式发布,拓展大语言模型时间和空间维度
  • 滚动条默认是隐藏的只有鼠标移上去才会显示
  • Go学习第十五章——Gin参数绑定bind与验证器