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. 文件不存在时不创建 四…

【C#】递归移动拷贝目录

当我们需要移动目录时&#xff0c;不能的简单的Directory.Move&#xff0c;这个方法不能支持递归迁移目录 需要我们进行递归进行迁移 void Main() {string sourcePath "D:\费用报销";string destinationPath "D:\文档\费用报销";// 确保源路径存在if (!D…

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

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

2024年,企业薪酬预算怎么做?

新的一年已经开始&#xff0c;许多企业的HR和财务部门正面临着薪酬预算的问题。预算数额过高&#xff0c;老板不会批准&#xff1b;而预算水平过低&#xff0c;则会引起员工不满。因此&#xff0c;薪酬预算是一项棘手的任务。然而&#xff0c;薪酬预算对企业的人力资源管理至关…

5.命令行提示符

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

使用 Go 实现 HelloWorld 程序,并分析其结构

在学习任何新的编程语言时&#xff0c;编写一个 “Hello, World” 程序通常是最初的入门步骤。这不仅是一个传统&#xff0c;也是一种快速了解语言基本语法和运行机制的有效方法。对于 Go 语言&#xff0c;这个过程不仅可以帮助新手快速入门&#xff0c;还提供了一个窗口&#…

一文读懂什么是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…

JAVA面试题大全(十六)

1、数据库的三范式是什么&#xff1f; 数据库的三范式是数据库设计中的三个基本原则&#xff0c;它们用于确保数据库的结构合理、数据冗余最小化&#xff0c;并提高数据的一致性。这三个范式分别是&#xff1a; 第一范式&#xff08;1NF&#xff09;&#xff1a;确保每个列都是…

机会就在眼前!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。。。然后。。…