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

【Android】SurfaceFlinger Dumpsys信息分析

SurfaceFlinger Dumpsys信息分析

dumpsys Surfaceflinger 用来输出SurfaceFlinger服务的状态信息,利用这些信息可以分析Android 画面层次、Display配置等等信息。

  • 本文基于Android14。

dumpsys的实现

dumpsys Surfaceflinger命令对应的源码实现如下

  • 源文件:frameworks/native/cmds/dumpsys/dumpsys.cpp
  • 函数:status_t Dumpsys::startDumpThread
status_t Dumpsys::startDumpThread(int dumpTypeFlags, const String16& serviceName,const Vector<String16>& args) {sp<IBinder> service = sm_->checkService(serviceName);if (service == nullptr) {std::cerr << "Can't find service: " << serviceName << std::endl;return NAME_NOT_FOUND;}int sfd[2];if (pipe(sfd) != 0) {std::cerr << "Failed to create pipe to dump service info for " << serviceName << ": "<< strerror(errno) << std::endl;return -errno;}redirectFd_ = unique_fd(sfd[0]);unique_fd remote_end(sfd[1]);sfd[0] = sfd[1] = -1;// dump blocks until completion, so spawn a thread..activeThread_ = std::thread([=, remote_end{std::move(remote_end)}]() mutable {if (dumpTypeFlags & TYPE_PID) {status_t err = dumpPidToFd(service, remote_end, dumpTypeFlags == TYPE_PID);reportDumpError(serviceName, err, "dumping PID");}if (dumpTypeFlags & TYPE_STABILITY) {status_t err = dumpStabilityToFd(service, remote_end);reportDumpError(serviceName, err, "dumping stability");}if (dumpTypeFlags & TYPE_THREAD) {status_t err = dumpThreadsToFd(service, remote_end);reportDumpError(serviceName, err, "dumping thread info");}if (dumpTypeFlags & TYPE_CLIENTS) {status_t err = dumpClientsToFd(service, remote_end);reportDumpError(serviceName, err, "dumping clients info");}// other types always act as a header, this is usually longerif (dumpTypeFlags & TYPE_DUMP) {// 走这里!!!!!status_t err = service->dump(remote_end.get(), args);reportDumpError(serviceName, err, "dumping");}});return OK;
}

其实,就是调用对应Service的dump函数。经过IPC,调用到SurfaceFlingerdoDump接口。

  • 源文件:frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
  • 函数:void SurfaceFlinger::setPowerMode
    这个函数中,SurfaceFlinger将服务的相关信息dump出来。
status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args, bool asProto) {std::string result;IPCThreadState* ipc = IPCThreadState::self();const int pid = ipc->getCallingPid();const int uid = ipc->getCallingUid();if ((uid != AID_SHELL) &&!PermissionCache::checkPermission(sDump, pid, uid)) {StringAppendF(&result, "Permission Denial: can't dump SurfaceFlinger from pid=%d, uid=%d\n",pid, uid);} else {static const std::unordered_map<std::string, Dumper> dumpers = {{"--comp-displays"s, dumper(&SurfaceFlinger::dumpCompositionDisplays)},{"--display-id"s, dumper(&SurfaceFlinger::dumpDisplayIdentificationData)},{"--displays"s, dumper(&SurfaceFlinger::dumpDisplays)},{"--edid"s, argsDumper(&SurfaceFlinger::dumpRawDisplayIdentificationData)},{"--events"s, dumper(&SurfaceFlinger::dumpEvents)},{"--frametimeline"s, argsDumper(&SurfaceFlinger::dumpFrameTimeline)},{"--hwclayers"s, dumper(&SurfaceFlinger::dumpHwcLayersMinidumpLocked)},{"--latency"s, argsDumper(&SurfaceFlinger::dumpStatsLocked)},{"--latency-clear"s, argsDumper(&SurfaceFlinger::clearStatsLocked)},{"--list"s, dumper(&SurfaceFlinger::listLayersLocked)},{"--planner"s, argsDumper(&SurfaceFlinger::dumpPlannerInfo)},{"--scheduler"s, dumper(&SurfaceFlinger::dumpScheduler)},{"--timestats"s, protoDumper(&SurfaceFlinger::dumpTimeStats)},{"--vsync"s, dumper(&SurfaceFlinger::dumpVsync)},{"--wide-color"s, dumper(&SurfaceFlinger::dumpWideColorInfo)},};const auto flag = args.empty() ? ""s : std::string(String8(args[0]));// Traversal of drawing state must happen on the main thread.// Otherwise, SortedVector may have shared ownership during concurrent// traversals, which can result in use-after-frees.std::string compositionLayers;mScheduler->schedule([&] {StringAppendF(&compositionLayers, "Composition layers\n");mDrawingState.traverseInZOrder([&](Layer* layer) {auto* compositionState = layer->getCompositionState();if (!compositionState || !compositionState->isVisible) return;android::base::StringAppendF(&compositionLayers, "* Layer %p (%s)\n", layer,layer->getDebugName() ? layer->getDebugName(): "<unknown>");compositionState->dump(compositionLayers);});}).get();bool dumpLayers = true;{TimedLock lock(mStateLock, s2ns(1), __func__);if (!lock.locked()) {StringAppendF(&result, "Dumping without lock after timeout: %s (%d)\n",strerror(-lock.status), lock.status);}if (const auto it = dumpers.find(flag); it != dumpers.end()) {(it->second)(args, asProto, result);dumpLayers = false;} else if (!asProto) {dumpAllLocked(args, compositionLayers, result);}}if (dumpLayers) {LayersTraceFileProto traceFileProto = mLayerTracing.createTraceFileProto();LayersTraceProto* layersTrace = traceFileProto.add_entry();LayersProto layersProto = dumpProtoFromMainThread();layersTrace->mutable_layers()->Swap(&layersProto);auto displayProtos = dumpDisplayProto();layersTrace->mutable_displays()->Swap(&displayProtos);if (asProto) {result.append(traceFileProto.SerializeAsString());} else {// Dump info that we need to access from the main threadconst auto layerTree = LayerProtoParser::generateLayerTree(layersTrace->layers());result.append(LayerProtoParser::layerTreeToString(layerTree));result.append("\n");dumpOffscreenLayers(result);}}}write(fd, result.c_str(), result.size());return NO_ERROR;
}

SurfaceFlinger Dump部分信息分析

SurfaceFlinger编译配置
Build configuration: 
[sf PRESENT_TIME_OFFSET=0 
FORCE_HWC_FOR_RBG_TO_YUV=1 
MAX_VIRT_DISPLAY_DIM=4096 
RUNNING_WITHOUT_SYNC_FRAMEWORK=0 
NUM_FRAMEBUFFER_SURFACE_BUFFERS=3]

sf:表示SurfacFlinger

PRESENT_TIME_OFFSET:垂直同步偏移,用来兼容垂直同步信号误差的(主要指跨进程的通知耗时),nanoseconds级别。

FORCE_HWC_FOR_RBG_TO_YUV:使用HWC进行 RGB到YUV的转换。

MAX_VIRT_DISPLAY_DIM:虚拟Display的最大尺寸,创建虚拟Display时,其宽或高要在这个范围内超过的话会创建失败。

RUNNING_WITHOUT_SYNC_FRAMEWORK: Sync同步框架是否开启,默认是开启的。

NUM_FRAMEBUFFER_SURFACE_BUFFERS:SurfaceFlinger中BufferQueue,一次申请Buffer时可以申请的最大数量(NUM_FRAMEBUFFER_SURFACE_BUFFERS减去1)。如果是3,减去1就是2.就是双Buffer机制。默认最高支持63个。一般都使用2,如果出现Jank情况下,可以适当调大(但是会更耗时系统资源)

显示器信息
Display identification data:
Display 100 (HWC display 0): invalid EDID

此处表示显示器信息(硬件信息)。EDID全称Extended Display Identification Data,存储在显示器寄存器中的一组有关于显示器属性值的信息。比如显示器名称、端口号之类。如果显示器没有提供这些信息,解析时就是显示ivalid EDID(PS此处显示的HWC,也就是PhysicalDisplay)

Wide-Color information:
Device supports wide color: 1
Device uses color management: 1
DisplayColorSetting: Managed
Display 100 color modes:ColorMode::NATIVE (0)Current color mode: ColorMode::NATIVE (0)

此处是显示器的色域信息,支持广色域、支持色彩管理、设置管理功能已经开启、支持1中颜色模式(Native)。
广色域是一种色彩背光技术,其色彩覆盖率能达到NSTC(National Television System Committe)标准的92%及以上。比如量子点LED背光能达到110%(比如AOC的量子点显示器大概在3499元)。使用广色域,可以让显示器的显示效果更佳鲜艳,但并不是NSTC覆盖标准越高越高,超过人眼的可识别范围的色彩是人类是无法分辨的(人眼识别范围(380~780nm)的光波波长。

Sync configuration: [using: EGL_ANDROID_native_fence_sync EGL_KHR_wait_sync]

这条信息表示,支持OpenGLES同步(Sync)。OpenGLES Sync依赖于两个扩EGL_ANDROID_native_fence_sync、EGL_KHR_wait_sync

Layer信息
Visible layers (count = 200)
Composition layers

当前显示的图层数目是200个

Display状态

Displays (1 entries) 有1个Display
Display 100(Display ID是 100)
connectionType=Internal (内置类型)
ColorMode::NATIVE (颜色模式为Native)
deviceProductInfo=nullopt (产品信息为空)
name="Primary display" 默认的Display
powerMode=Off (电源状态是OFF)
activeMode=60.00 Hz (60.00 Hz) (刷新率是60帧)

  • 如果通过scrpy投屏可以看到对应的Virtual Display
Virtual Display 12529715046768705014name="scrcpy"powerMode=On

其他信息省略。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • openVX加速-结合AI推理引擎代码示例
  • 集群聊天服务器项目【C++】(三)muduo库的简单介绍
  • 网页模板该怎么选
  • MVC 控制器
  • Java | Leetcode Java题解之第401题二进制手表
  • yolov8 rect batch_shapes 672 图像大小变化
  • PHP智驭未来悦享生活智慧小区物业管理小程序系统源码
  • Java的发展史与前景
  • SQL Server详细使用教程(包含启动SQL server服务、建立数据库、建表的详细操作) 非常适合初学者
  • 4G模块、WIFI模块、NBIOT模块通过AT指令连接华为云物联网服务器(MQTT协议)
  • 高效数据移动指南 | 如何快速实现数据库 MySQL 到 MongoDB 的数据同步?
  • Python selenium 破解腾讯滑块行为验证码
  • 【Hadoop|MapReduce篇】Hadoop序列化概述
  • 【运维监控】influxdb 2.0+grafana 监控java 虚拟机以及方法耗时情况(完整版)
  • RTC、ADC
  • 【mysql】环境安装、服务启动、密码设置
  • ➹使用webpack配置多页面应用(MPA)
  • 2017 年终总结 —— 在路上
  • Centos6.8 使用rpm安装mysql5.7
  • Create React App 使用
  • create-react-app做的留言板
  • HTTP中GET与POST的区别 99%的错误认识
  • LeetCode算法系列_0891_子序列宽度之和
  • 网络应用优化——时延与带宽
  • Unity3D - 异步加载游戏场景与异步加载游戏资源进度条 ...
  • 阿里云ACE认证学习知识点梳理
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • ​什么是bug?bug的源头在哪里?
  • #QT(TCP网络编程-服务端)
  • $nextTick的使用场景介绍
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (1)虚拟机的安装与使用,linux系统安装
  • (C)一些题4
  • (day 12)JavaScript学习笔记(数组3)
  • (LeetCode 49)Anagrams
  • (八)Flink Join 连接
  • (补)B+树一些思想
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (六)vue-router+UI组件库
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转载)Google Chrome调试JS
  • ***详解账号泄露:全球约1亿用户已泄露
  • .axf 转化 .bin文件 的方法
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .Net CF下精确的计时器
  • .net core webapi 大文件上传到wwwroot文件夹
  • .NET 中 GetProcess 相关方法的性能
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • /deep/和 >>>以及 ::v-deep 三者的区别
  • :“Failed to access IIS metabase”解决方法
  • @Async 异步注解使用