Android -- SurfaceFlinger 合成主线程 系列 (三)

【surfaceflinger源码分析】RenderSurface与FramebufferSurface之间的关系 surfaceflinger中合成时,合成之后的数据bufferqueue的生产者和消费之之间的关系,RenderSurface与FramebufferSurface的关系 阅读详情
SurfaceFlinger 属于system_server进程,在system_init.cpp中利用SurfaceFlinger::instantiate()启动,在此加入到service manager中,所以本身提供service服务功能。


首先看下SurfaceFlinger的类声明:

class SurfaceFlinger :
        public BinderService<SurfaceFlinger>,
        public BnSurfaceComposer,
        protected Thread



从接口可以看出使用Binder与客户端通讯,并且继承线程 Thread 类,则循环执行threadLoop。完成系统中的各个Layer-Surface进行混合,然后将一帧帧混合好的图像传送到显示framebuffer中。


其主线程工作流程图如下:




下面就这以上图五步将代码一一过一遍:
1、waitForEvent() 等待什么事情呢?


void SurfaceFlinger::waitForEvent()
{
    while (true) {
     ......
    
       sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
     ......
        if (msg != 0) {
            switch (msg->what) {
             //等的就是这个消息事件哟。。。。
                case MessageQueue::INVALIDATE:
                    // invalidate message, just return to the main loop
                    return;
            }
        }    
  }
}



原来是等待收到MessageQueue::INVALIDATE重绘消息才退回到主线程,那么这个消息由谁来发送呢?


请看下面代码:

void SurfaceFlinger::signalEvent() {
    mEventQueue.invalidate();
}


void SurfaceFlinger::signal() const {
    // this is the IPC call
    const_cast<SurfaceFlinger*>(this)->signalEvent();
}


这是就是发送消息的点,这个函数signalEvent由谁来调用呢?其个这个发起都是上一节说的,在释放Surface对应的显示缓冲区需要显示时调用:
unlockAndPost() --> queueBuffer() --> mClient.signalServer() --> SurfaceFlinger::signal()


2、handlePageFlip()  
该阶段会遍历各个Layer,在每个Layer中,取得并锁住该Layer的frontBuffer,然后利用frontBuffer 中的图像数据生成该Layer的2D贴图(Texture),并且计算更新区域,为后续的混合操作做准备。


void SurfaceFlinger::handlePageFlip()
{
//调用 lockPageFlip
visibleRegions |= lockPageFlip(currentLayers);

//取得屏幕的区域
const Region screenRegion(hw.bounds());
if (visibleRegions) {
   Region opaqueRegion;
   computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
   .....
   mWormholeRegion = screenRegion.subtract(opaqueRegion);
}
.....
//调用 unlockPageFlip
unlockPageFlip(currentLayers);
}


上面的调用实际上是一对函数:lockPageFlip & lockPageFlip,那么主要干些啥呢?


bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
{
    bool recomputeVisibleRegions = false;
    size_t count = currentLayers.size();
    sp<LayerBase> const* layers = currentLayers.array();


    //逐个 layer 进行处理 
    for (size_t i=0 ; i<count ; i++) {
        const sp<LayerBase>& layer(layers[i]);
        layer->lockPageFlip(recomputeVisibleRegions);
    }
    return recomputeVisibleRegions;
}


void Layer::lockPageFlip(bool& recomputeVisibleRegions)
{
SharedBufferServer* lcblk(sharedClient.get());

// 获取当前可用的 frontbuffer 索引号
ssize_t buf = lcblk->retireAndLock();

// 计算当前的脏区域
  sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
  if (newFrontBuffer != NULL) {
      // get the dirty region
      // compute the posted region
      const Region dirty(lcblk->getDirtyRegion(buf));
      mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
      ....

// 如果有脏区域需要重绘,则生成 OpenGL ES 纹理贴图
reloadTexture( mPostedDirtyRegion );
}


void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
{
    const GraphicPlane& plane(graphicPlane(0));
    const Transform& planeTransform(plane.transform());
    size_t count = currentLayers.size();
    sp<LayerBase> const* layers = currentLayers.array();
    for (size_t i=0 ; i<count ; i++) {
        const sp<LayerBase>& layer(layers[i]);


//进行区域的清理工作
        layer->unlockPageFlip(planeTransform, mDirtyRegion);
    }
}


void Layer::unlockPageFlip(
        const Transform& planeTransform, Region& outDirtyRegion)
{
    Region dirtyRegion(mPostedDirtyRegion);
    if (!dirtyRegion.isEmpty()) {
        mPostedDirtyRegion.clear();
....
    if (visibleRegionScreen.isEmpty()) {
        // an invisible layer should not hold a freeze-lock
        // (because it may never be updated and therefore never release it)
        mFreezeLock.clear();
    }
}


以上的工作就是按照 Zorder 序计算自已屏幕上的可显示区域:
1、以自己的W,H给出自己初始的可见区域
2、减去自己上面窗口所覆盖的区域






3、handleRepaint
每个Layer的数据都准备好了,并且各个脏区域也计算ok,下步就是根据 Zorder 序从底部将数据绘制到主Surface上


void SurfaceFlinger::handleRepaint()
{
    // compute the invalid region
    mInvalidRegion.orSelf(mDirtyRegion);


....


    // compose all surfaces
    composeSurfaces(mDirtyRegion);


    // clear the dirty regions
    mDirtyRegion.clear();
}


void SurfaceFlinger::composeSurfaces(const Region& dirty)
{
...
    const size_t count = layers.size();
    for (size_t i=0 ; i<count ; ++i) {
        const sp<LayerBase>& layer(layers[i]);
        const Region clip(dirty.intersect(layer->visibleRegionScreen));
        if (!clip.isEmpty()) {
            // 这就是绘图核心函数
            layer->draw(clip);
        }
    }
}



void Layer::onDraw(const Region& clip) const
---> drawWithOpenGL(clip, tex); 基本上都是OpenGL ES 操作函数


    while (it != end) {
        const Rect& r = *it++;
        const GLint sy = fbHeight - (r.top + r.height());
        // 裁剪
        glScissor(r.left, sy, r.width(), r.height());
        // 画矩形
        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    }

4、unlockClients()
释放 handlePageFlip 占用的 frontbuffer 索引号,以便客户端可以继续在新的surface画图


void SurfaceFlinger::unlockClients()
{
...
    for (size_t i=0 ; i<count ; ++i) {
        const sp<LayerBase>& layer = layers[i];
        layer->finishPageFlip();
    }
}


-->
SharedBufferServer* lcblk(sharedClient.get());
status_t err = lcblk->unlock( buf );



5、postFramebuffer()
现在已经将所有的Layer图层数据合成完成,最后就是输入到屏幕上显示了



void SurfaceFlinger::postFramebuffer()
{
//调用此函数将混合后的图像传递到屏幕中进行显示
hw.flip(mInvalidRegion);
...
}


void DisplayHardware::flip(const Region& dirty) const
{
// 显示图像吧。。。。。
    eglSwapBuffers(dpy, surface);

}


Andorid Surface(3.3) android Surface(3.3) 阅读详情

相关推荐

SurfaceFlinger layer之间的对应关系

本文详细分析了SurfaceFligner中Layer流转的过程,以便于了解SurfaceFlinger的合成过程

fengchaochao123的博客 2579

SurfaceFlinger -- FramebufferSurface 详解

1: FramebufferSurface 概述 FramebufferSurface 根据名字解析: 1: Surface 说明它是一个Surface, 那么它就会拥有一个 BufferQuere, 用于显示。 2: FrameBuffer 这和 Linux 的 framebuffer 是完全不同的。 但是作用有些类似, SurfaceFlinger 在上面作画, 并把它交给HWC, 最终

ouo555的专栏 8792

Android13 SurfaceFlinger合成流程深度解析:从HWC到GPU的混合合成策略

本文深度解析了Android13系统中SurfaceFlinger的图形合成流程,重点剖析了其混合合成策略。文章详细阐述了从VSync信号触发,到HWC硬件合成器与GPU协同工作的完整决策链路,包括合成规划、状态更新及最终的帧提交,揭示了系统如何在性能与功耗间取得平衡,为开发者优化图形性能提供了核心洞见。

9o8p7i6u5y的博客 936

GUI系统之SurfaceFlinger(15)handlePageFlip

文章都是通过阅读源码分析出来的,还在不断完善与改进中,其中难免有些地方理解得不对,欢迎大家批评指正。转载请注明:From LXS. http://blog.youkuaiyun.com/uiop78uiop78/GUI系统之SurfaceFlinger章节目录:blog.youkuaiyun.com/uiop78uiop78/article/details/89545081.1.1 handlePageFlipPageF

林学森的技术专栏 9412

Android显示系统之SurfaceFlinger(一)

1.1 SurfaceFlinger的启动SurfaceFlinger的启动和ServiceManager有点类似,它们都属于系统的底层支撑服务,必需在设备开机的早期就运行起来。/*frameworks/base/cmds/system_server/library/System_init.cpp*/extern "C" status_t  system_init(){…       proper

林学森的技术专栏 1万+

SurfaceFlinger工作流程

SurfaceFlinger 是 Android 图形系统的核心合成引擎,负责将所有应用的图形层(Layer)合成为最终帧并输出到显示设备,其工作流程严格依赖 VSync 信号驱动,主要分为以下阶段: 此流程确保所有图形更新严格按屏幕刷新节奏(如 60Hz)执行,避免画面撕裂并优化资源开销。引用链接: 1.SurfaceFlinger初始化流程 - 优快云博客 2.SurfaceFlinger启动流程 - 优快云博客 3.Android Systrace 基础知识 - SurfaceFlinger 解读

summerkissyou1987的专栏 1205

Android SurfaceFlinger

SurfaceFlinger是Android系统中的一个重要组件,它主要负责窗口管理与界面显示。具体来说,SurfaceFlinger作为系统的显示引擎,负责接收各应用程序发来的图像数据,并组合成一张完整的画面,并输出到显示屏上。SurfaceFlinger通过重绘整个屏幕或部分屏幕来更新UI界面。它还提供了多种硬件加速技术,如OpenGL ES、Vulkan等,使应用程序能够更快地渲染UI界面。SurfaceFlinger还支持窗口叠加、透明度、混合模式等特性,以支持复杂的多层UI界面。

liuning1985622的博客 3957

Android 渲染引擎——SurfaceFlinger 合成流程与性能优化

本文深入解析Android渲染引擎SurfaceFlinger的合成流程与性能优化策略。从核心的生产者-消费者模型到硬件协作机制(HWC与OpenGL ES),详细探讨了图层合成、缓冲队列选择及实战性能排查方法,帮助开发者优化UI流畅度,解决卡顿问题。

weixin_42520025的博客 379

Android 图形系统之七:SurfaceFlinger

SurfaceFlinger 是 Android 系统中一个极为关键的系统服务,处于图形显示架构的核心位置,主要负责将各个应用层提供的 Surface(代表可视化的界面元素)进行合成,并最终输出到屏幕显示,起到了承上启下的桥梁作用,衔接应用层与硬件显示层。

执剑人 8841

surfaceflinger的启动

surfaceflinger的源码路径如下: frameworks/native/services/surfaceflinger/ - main_surfaceflinger.cpp - SurfaceFlinger.cpp - DispSync.cpp - MessageQueue.cpp - DisplayHardware/HWComposer.cpp frameworks/native/libs/gui/ - DisplayEventReceiver.cpp - BitT

qq_34888036的博客 2229

Android 图形架构 之二—— SurfaceFlinger 启动和连接

上一篇文章从全局来分析了Android 图形架构,本篇文章来分析SurfaceFlinger,surface的创建、图像的处理,管理设备的帧缓冲区等等,它是图像流的消费者,是本系列文章的核心 SurfaceFlinger的启动过程 启动概述 SurfaceFlinger服务是一个独立进程。 关于硬件方面的服务都在 frameworks/native/services/ 文件夹下,例如:audiomanager、powermanager、inputflinger、sensorservice、surfacefl

薛瑄的博客 7186

【Android FrameWork】延伸阅读:SurfaceFlinger线程

本文深入解析了Android SurfaceFlinger的核心线程模型及其工作机制。SurfaceFlinger通过多线程分工实现高性能图形渲染,主要包括: 主线程负责服务初始化、Binder请求处理和全局状态管理,其核心逻辑在Looper循环中运行,确保轻量化以避免阻塞。 VSyncThread作为硬件同步信号的监听者,从Display HAL获取VSync事件并转发给EventThread,是整个渲染流程的时钟基准。 EventThread负责VSync信号的分发调度,通过事件队列机制协调应用渲染和S

u012739527的博客 1431

Android SurfaceFlinger——服务启动流程(二)

由 init 进程启动:SurfaceFlinger 服务作为 Android 系统中的一个关键服务,是由 init 进程根据 init.rc 配置文件启动的。在这个阶段,init 进程会 fork 出一个新的进程来运行 SurfaceFlinger 服务。

小旭的专栏 1765

Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer与fence机制(2)

t 时长,20s,20秒的trace文件。CPU返回后,会直接将GraphicBuffer提交给SurfaceFlinger,告诉SurfaceFlinger进行合成,但是这个时候GPU可能并未完成之前的图像渲染,这时候就牵扯到一个同步,Android中,用的是Fence机制,SurfaceFlinger合成前会查询Fence,如果GPU渲染没有结束,则等待GPU渲染结束,GPU结束后,会通知SurfaceFlinger进行合成,SF合成后,提交显示,最终完成图像的渲染显示。就是 Buffer。

Zhang Phil 4629

python爬取淘宝数据

python爬取淘宝数据淘宝评论 淘宝评论 打开淘宝,选择打开需要爬取的商品的评论。在谷歌浏览器选择开发者工具,选择network,找到list_detail_rate.htm?itemId=624466733121,点击headers、previews,可以看见相应的评论数据。 爬取一页屏评论代码如下 import re import requests headers = { 'Referer': '在headers中', 'User-Agent': '在

qq_36333776的博客 5798

保姆级教程:用Kvaser DB Editor从零创建你的第一个DBC文件(附CAN信号属性详解)

本文提供了一份详细的Kvaser DB Editor教程,指导用户从零开始创建DBC文件,并深入解析CAN信号属性的关键设置。通过步骤清晰的安装指南、信号属性配置详解和实用技巧,帮助工程师和学生快速掌握CAN总线通信的核心工具,提升工作效率。

weixin_27076351的博客 250

SurfaceFlinger源码摘要

Android中两个主要的服务,AMS(ActivityManagerService)和WMS(WindowManagerService). View,AMS,WMS可以说是整个上层显示系统的三驾马车 在Android中,一个窗口用一个Surface描述。多个窗口(窗口不一定都是Activity),需要同时显示,我们就需要将多个窗口进行合并。 Surfaceflinger控制窗口的合成,将多个窗口合并成一个,再送到LCD。 Surfaceflinger是Native的服务. Surfaceflinger中怎

fdsafwagdagadg6576的专栏 1811

IEEE Access 上岸指南,附含泪整理的 cover letter 、沟通邮件、终版文档等资料包

终于上岸了! 我是一个小硕,本科期间发表过两篇水文,奈何学校有更高的毕业要求,只能硬着头皮尝试一下 SCI。 想投 IEEE Access 的朋友都应该知道 小木虫论坛 对这个期刊的讨论,褒贬不一,有的人说是大水刊,有的人说有难度。 比如: @wow_: 不可否认,灌水期刊。只要之前中过一篇,再投基本没有不录用的!我们实验室其他老师说过一区除外的收费期刊都应该禁止灌水。 @pssp: 审稿人还...

kurryluo的博客 1万+

Android图形显示系统——下层显示4:图层合成上(合成原理与3D合成)

Android显示之图层合成要点1.图层合成指综合各个窗口的绘制内容,送往LCD显示的过程。从原理上可分为在线合成与离线合成两种方式。 2.在Android的SurfaceFlinger代码流程中,图层合成方式分3D合成(OpenGL)和硬件合成两大类。 3.图形系统采用垂直同步Vsync机制,由LCD上报vsync,触发图层合成。图层合成的原理什么是图层合成以Android原生版本的Launc

jxt1234and2010的专栏 1万+

普通人如何上岸华为OD-面试总结

总共有3道算法题,100分值的两道,200分值的一道,不同的毕业院校和专业,通过机试的分值不一样,最少需要150分通过,提前和hr联系,了解自己需要多少分通过。重中之重:哪怕你是背的题库,也请你一定不要直接抄原来的,最好是变更下方法名,否则会判定你重复率过高,从而失去后面的面试机会(实在是不会做再用此方法,凑分数所用,面试官能看到你的代码,会影响你的面试评价)本人女,所以还问道了婚育计划,有对象这点可以说,没有问题,但是如果可以的话,生孩子的时间,可以给hr说这几年不考虑。如果说没有难题,直接就挂了。

weixin_47767264的博客 5455

基于GPU的GEMM矩阵相乘运算优化

从上图中我们可以看到三种处理方法。第一种是将A和B矩阵分块,第二种方法是将C和B矩阵分块,第三种方法是将C和A矩阵分块。GEMM的子任务是GEPP或GEMP;最小粒度的任务是GEBP或GEPB或点乘。

weixin_55035144的博客 2156

SurfaceFlinger启动-Android12

SurfaceFlinger启动-Android12

许浑的博客 3047

Word2vec核心模型精讲:CBOW与Skip-gram

Word2vec是Google提出的词向量模型,通过CBOW和Skip-gram两种神经网络架构将词汇映射到低维向量空间。CBOW通过上下文预测中心词,训练速度快但高频词表现更好;Skip-gram则相反,通过中心词预测上下文,适合处理生僻词。为解决softmax计算效率问题,Word2vec引入基于哈夫曼树的Hierarchical Softmax优化技术,将复杂度从O(V)降至O(logV)。文章详细解析了两种模型的原理差异,并演示了哈夫曼树的构造过程及其在词向量训练中的关键作用,这种结合词频的优

Trisyp的博客 530
上一篇: VNCServer 使用
下一篇: Ubuntu10.04 常用配置
andyhuabing
博客等级 码龄19年 704粉丝 165原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值