SurfaceFinger layer创建过程

SurfaceFinger layer创建过程


引言

本篇博客重点分析app创建Surface时候,SurfaceFlinger是如何构建对应的Layer的主要工作有那些!

这里参考的Android源码是Android 13 aosp!




app端创建Surface

其核心流程可以分为如下接部分:

  • app使用w,h,format等参数,调用SurfaceComposerClient::createSurface

  • createSurface调用SurfaceComposerClient::createSurfaceChecked;createSurfaceChecked调用mClient->createSurface;mClient是surfaceflinger client的代理;mClient的初始化还没介绍,后面单独写一篇介绍。

  • mClient->createSurface会调用到android12\frameworks\native\services\surfaceflinger\Client.cpp 中Client::createSurface

  • Client::createSurface调用mFlinger->createLayer

核心逻辑代码如下:

surfaceComposerClient->createSurface(String8("SurfaceTestDemo"), resolution.getWidth(),resolution.getHeight(), PIXEL_FORMAT_RGBA_8888,ISurfaceComposerClient::eFXSurfaceBufferState,/*parent*/ nullptr);sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,PixelFormat format, uint32_t flags,const sp<IBinder>& parentHandle,LayerMetadata metadata,uint32_t* outTransformHint) {sp<SurfaceControl> s;createSurfaceChecked(name, w, h, format, &s, flags, parentHandle, std::move(metadata),outTransformHint);return s;
}status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,PixelFormat format,sp<SurfaceControl>* outSurface, uint32_t flags,const sp<IBinder>& parentHandle,LayerMetadata metadata,uint32_t* outTransformHint) {status_t err = mStatus;if (mStatus == NO_ERROR) {sp<IBinder> handle;sp<IGraphicBufferProducer> gbp;err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),&handle, &gbp, &id, &transformHint);*outSurface =new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);}return err;
}

image

image



SurfaceFlinger端创建layer过程

SurfaceFlinger构建Layer的核心流程如下:

  • 根据app的flags确定创建layer类型createBufferStateLayer;createEffectLayer还是createContainerLayer;目前尚不清楚不同layer之间的区别,以createBufferStateLayer为例

  • 将传入参数放入LayerCreationArgs args,调用getFactory().createBufferStateLayer(args)创建BufferStateLayer;获取layer handle,并返回

  • 调用SurfaceFlinger::addClientLayer,创建LayerCreatedState,放入mCreatedLayers[handle->localBinder()];使用handle等参数创建composerState,并传入SurfaceFlinger::setTransactionState

  • 创建TransactionState state,并将其放入mTransactionQueue.emplace(state)


这里我们重点看下SurfaceFlinger::addClientLayer的实现,因为后面会用到它。

status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBinder>& handle,const sp<Layer>& layer, const wp<Layer>& parent,bool addToRoot, uint32_t* outTransformHint) {
...                                        {std::scoped_lock<std::mutex> lock(mCreatedLayersLock);mCreatedLayers.emplace_back(layer, parent, addToRoot);}       // attach this layer to the clientif (client != nullptr) {client->attachLayer(handle, layer);mLayers.add(handle, layer);        }   setTransactionFlags(eTransactionNeeded) //提交eTransactionNeeded...    
}//这个什么时候会触发这个transaction呢,大概流程如下:MessageQueue::Handler::handleMessage(...)//frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cppcompositor.commit()//这里的compositor指向SurfaceFlingerif (clearTransactionFlags(eTransactionFlushNeeded)) {needsTraversal |= commitCreatedLayers();needsTraversal |= flushTransactionQueues(vsyncId);}bool SurfaceFlinger::commitCreatedLayers() {for (const auto& createdLayer : createdLayers) {handleLayerCreatedLocked(createdLayer);}    
}void SurfaceFlinger::handleLayerCreatedLocked(const LayerCreatedState& state) {sp<Layer> layer = state.layer.promote();if (!layer) {ALOGD("Layer was destroyed soon after creation %p", state.layer.unsafe_get());return;}sp<Layer> parent;bool addToRoot = state.addToRoot;if (state.initialParent != nullptr) {parent = state.initialParent.promote();if (parent == nullptr) {ALOGD("Parent was destroyed soon after creation %p", state.initialParent.unsafe_get());addToRoot = false;}}if (parent == nullptr && addToRoot) {layer->setIsAtRoot(true);mCurrentState.layersSortedByZ.add(layer);//注意这里对应的Layer是BufferStateLayer} else if (parent == nullptr) {layer->onRemovedFromCurrentState();} else if (parent->isRemovedFromCurrentState()) {parent->addChild(layer);layer->onRemovedFromCurrentState();} else {parent->addChild(layer);}layer->updateTransformHint(mActiveDisplayTransformHint);mInterceptor->saveSurfaceCreation(layer);
}

其中SurfaceFlinger端各种Layer的关系如下:

在这里插入图片描述


image


== 这里需要注意的点是==:

  • SurfaceFlinger::setTransactionState中比较复杂容易忽略将TransactionState state放入mTransactionQueue的过程,mTransactionQueue在后面创建hwc layer的时候会用到



遗留思考问题

在Android 11中添加了一个彩蛋就是增加了BLASTBufferQueue,这个我们要怎么理解它呢!它的核心作用就是将Android GraphicBuffer的管理全部交由App应用端处理,而不经过SurfaceFlinger处理。这里我存在的疑问就是:

  • App端渲染完成之后,怎么将这些buffer提交给SurfaceFlinger进行继续处理呢!
  • App端申请的Surface Buffer怎么和SF端对应的Layer关联起来呢
  • App端构建的SurfaceControl在App端和SurfaceFlinger的交互中的作用是什么

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/842939.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

window.location.search取不到值

window.location.search window.location.search没有值的原因&#xff1a; URL中使用了 hash &#xff08;指URL中带有#符号&#xff09;,导致URL后面携带的参数被location.hash截取走了&#xff0c;你再使用window.location.search得到的就是空值 打印 window.location 其实…

收银系统源码--零售连锁店铺如何选择适合自己的收银系统?

如果你现在还认为小便利店只要简单的收款&#xff0c;只有大型的连锁便利店才需要收银软件和管理软件&#xff0c;那你就错了&#xff0c;连锁品牌的便利店是必须要用到专业的收银软件&#xff0c;但是小微型的便利店更应该要用专门的软件&#xff0c; 在各行各业逐步革新互联网…

ORCLE删除数据库文件

在实际操作中很少会去删除数据库文件&#xff0c;但是凡事都有例外&#xff0c;由于一些特殊原因&#xff0c;例如存储方式变化、磁盘空间不够等&#xff0c;需要调整和删除一些无效的数据库文件&#xff0c;本文介绍一下实践出来的一种删除数据库文件的操作方式。 删除前请对数…

Linux系统之touch命令的基本使用

Linux系统之touch命令的基本使用 一、touch命令介绍1. touch命令简介2. touch命令作用 二、touch命令帮助1. touch命令的帮助信息2. touch命令的选项解释 三、touch命令的基本使用1. 查看touch工具版本2. 创建空文件3.查看空文件属性4. 修改文件时间戳5. 文件不存在时不创建 四…

概率分布函数与误差函数的关系

正态函数&#xff08;高斯分布&#xff09; 对其求[b,x]区间的积分 标准误差函数 以下两个方程相等&#xff08;a,b取值任意&#xff09; 两个函数重合 可知正态函数 f(t) 在[b,x]的区间上积分等于 引用desmos计算器&#xff1a;Desmos | Lets learn together.

5.命令行提示符

一、打开终端&#xff08;有以下几种方式&#xff09; 1.在搜索框输入 terminal 2.命令 &#xff08;1&#xff09;ctrlaltt打开新的终端 &#xff08;2&#xff09;ctrlshiftt&#xff1a;在已经打开终端的基础内&#xff0c;新打开一个同路径的终端。 &#xff08;3&#xf…

一文读懂什么是PaaS平台

如今&#xff0c;数字化概念广为流传&#xff0c;数字化转型的重要性也不言而喻。在转型过程中&#xff0c;企业不仅需要高效地管理业务流程&#xff0c;还需要不断创新和适应市场变化。在这样的背景下&#xff0c;PaaS平台应运而生&#xff0c;成为了企业实现创新、提升效率的…

充电宝哪家好用推荐?买什么充电宝性价比高?2024年充电宝排行榜

说实话&#xff0c;我其实是个手机重度使用者&#xff0c;买过的充电宝也有无数款了&#xff0c;每次手机没电的时候插座都离得不是特别近&#xff0c;不是要下床充电就是要固定在一个位置充电感觉怪麻烦的&#xff0c;但是有了充电宝后可以在床上玩手机都不用担心手机没电&…

1131. 绝对值表达式的最大值

1131. 绝对值表达式的最大值 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;_1131绝对值表达式的最大值 错误经验吸取 原题链接&#xff1a; 1131. 绝对值表达式的最大值 https://leetcode.cn/problems/maximum-of-absolute-value-expr…

机会就在眼前!2025-CISP深圳国际体育展的招展工作火热持续中...

2025-CISP中国&#xff08;深圳&#xff09;国际体育展的招展工作火热持续中&#xff0c;凭借越来越深远的影响力以及前两届的成功举办经验&#xff0c;展位多半已被“抢购”。但小编的同事们同时又反映出一个问题&#xff1a;有一批老展商和新展商已有明确的参展意向&#xff…

第十三周 5.27面向对象的三大特性(封装、继承、多态)(三)

3.instanceof避免类型转换异常: (1)语法:引用名 instanceof 类名 (2)执行:判断引用中存储的实际对象类型是否兼容于后面的类型(是否为后面类型的一种)&#xff0c;兼容一true&#xff0c;不兼容—false (3)作用:可以在程序设计中避免类型转换异常 直接使用案例…

C# 中 async 与 await 关键字详解

async 和 await 关键字的作用是使方法能够异步执行并等待异步操作的完成。&#xff08;最重要的一点是记住 “异步执行”与“等待异步操作完成”&#xff0c;不是等待主线程操作完成&#xff09; async 修饰符可将 方法、lambda 表达式或匿名方法指定为异步。 async 关键字用于…

TS(TypeScript)中Array数组无法调出使用includes方法,显示红色警告

解决方法 打开tsconfig.json文件&#xff0c;添加"lib": ["es7", "dom"]即可。 如下图所示。

如何使用Spring Cache优化后端接口?

Spring Cache是Spring框架提供的一种缓存抽象,它可以很方便地集成到应用程序中,用于提高接口的性能和响应速度。使用Spring Cache可以避免重复执行耗时的方法,并且还可以提供一个统一的缓存管理机制,简化缓存的配置和管理。 本文将详细介绍如何使用Spring Cache来优化接口,…

nginx开启资源目录

nginx开启资源目录表 可访问开放资源目录下的任何文件以及视频&#xff0c;图片等。可以作为一个妥妥的线上网盘资源托管空间使用。 上一篇文档揭示了nginx的神秘面纱&#xff0c;初步介绍与启动了nginx的基本功能和使用前端nginx学习配置开发验证&#xff0c;对各种配置已经…

rm命令处理(防止误删)

文章目录 前言&#xff1a;一、添加回收站脚本二、测试1.rm命令测试2.清理回收站 三、自动建立回收站脚本总结 前言&#xff1a; 前几天本来想对开发板上的内容进行一个转移&#xff0c;一边心想这直接mv -rf * dir不就行了嘛&#xff0c;一边打上了rm -rf * dir。。。然后。。…

Nacos源码本地用idea启动不了 Unable to start embedded Tomcat

1.报错 org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcatat org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:142)at org.springframework.boot.web.embedded.tomcat.TomcatWebSe…

UE5 CommonUI的使用(附源码版)

UE5 CommonUI的使用 前言快速配置配置Game Viewport Client ClassCommonGameViewportClient源代码 创建CommonInputAction表默认导航Action设置CommonUIInputData源码 Bind CommonInputBaseControllerDataCommonInputBaseControllerData源码 Common UI控件库和控件样式CommonUs…

U8G2移植到STM32,SSD13XXXOLED(硬件SPI DMA通讯)

文章目录 一、前言1.1 U8g2的特点1.2 U8G2的优势1.3 U8G2的下载地址1.4 U8g2支持的显示控制器 二、STM32Cubexm SPI DMA配置2.1 SPI设置为半双工模式2.2 SPI DMA设置2.3 oled其他引脚配置 三、移植U8G2框架3.1 精简U8G2库文件3.2 去掉csrc文件夹中无用的驱动文件3.3 文件移动到…

庆余年2火了,却把热爱开源的程序员给坑了

庆余年 2 终于开播了&#xff0c;作为一名剧粉&#xff0c;苦等了五年终于盼来了。开播即爆火&#xff0c;虽然首播的几集剧情有些拖沓&#xff0c;不过也不影响这是一部好剧。 然而&#xff0c;庆余年 2 的爆火&#xff0c;却把 npmmirror 镜像站给坑惨了。npmmirror 镜像站&…