【Android】SurfaceFlinger Dumpsys信息分析

news2024/9/17 7:49:57

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 longer
        if (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 thread
                const 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 12529715046768705014
    name="scrcpy"
    powerMode=On

其他信息省略。

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

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

相关文章

算法练习题18——leetcode240搜索二维矩阵||(二分)

题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 代码 class Solution {public boolean searchMatrix(int[][] matrix, int target) {for(int[…

双指针(6)_单调性_查找总价格为目标值的两个商品

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 双指针(6)_单调性_查找总价格为目标值的两个商品 收录于专栏【经典算法练习】 本专栏旨在分享学习C的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#…

DuPL: Dual Student with Trustworthy Progressive Learning for Robust WSSS

摘要 近年来&#xff0c;具有图像级标签的单阶段弱监督语义分割(WSSS)因其简化了其繁琐的多阶段语义分割而获得了越来越多的关注。由于类激活图(Class Activation Map, CAM)固有的模糊性&#xff0c;我们观察到一级管道经常会遇到由错误的CAM伪标签引起的确认偏差&#xff0c;…

基于SpringBoot的图书馆座位预约系统+小程序+LW参考示例

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

继电器的使用

本文为大家讲一下继电器的常规使用. 添加 在菜单中选择 “绘制–无源元件–添加继电器(relay)” 以添加继电器. 或者用 shiftr(大写) 这个快捷键 继电器由一个线圈和该线圈所控制的铁质弹性开关(衔铁)组成. 原理 它的原理如下: 上面的铁质弹性开关, 默认情况下在弹力作用下…

java基础概念22-抽象类

一、抽象类的引入 1-1、封装 问题&#xff1a;javabean越来越多。重复的内容越多——继承 1-2、继承 二、抽象类、抽象方法 一个方法抽取到父类中&#xff0c;不确定方法体——抽象方法 定义了抽象方法的类——抽象类。 在Java中&#xff0c;抽象类是一种特殊的类&#xff0c…

博士生锻炼记录:2024.9.8

读博三年来感觉身体状况大不如前&#xff0c;虽然博士生的主要任务就是做课题和发文章&#xff0c;但是身体健康也是不容忽视的一环&#xff0c;一个好的身体是做好任何事情的基础&#xff0c;我们应该在不影响身体健康的前提下努力做课题。 这周初去参加了一个体成分测量的活…

Python编码系列—Python项目管理:掌握高效工具与实践

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

YOLOv9改进策略【Neck】| 使用CARAFE轻量级通用上采样算子

一、本文介绍 本文记录的是利用CARAFE上采样对YOLOv9的颈部网络进行改进的方法研究。YOLOv9采用传统的最近邻插值的方法&#xff0c;仅考虑子像素邻域&#xff0c;无法捕获密集预测任务所需的丰富语义信息&#xff0c;从而影响模型在密集预测任务中的性能。CARAFE通过在大感受…

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包&#xff0c; 通常我们会使用nohup直接启动&#xff0c;但是还是需要手动停止然后再次启动&#xff0c; 那如何更优雅的在服务器上启动jar包呢&#xff0c;让我…

设计模式之工厂模式(通俗易懂--代码辅助理解【Java版】)

文章目录 1、工厂模式概述1&#xff09;特点&#xff1a;2&#xff09;主要角色&#xff1a;3&#xff09;工作流程&#xff1a;4&#xff09;优点5&#xff09;缺点6&#xff09;适用场景 2、简单工厂模式(静态工厂模式)1) 在简单工厂模式中&#xff0c;有三个主要角色&#x…

基于SpringBoot的宠物服务系统+uniapp小程序+LW参考示例

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

浏览器插件利器--allWebPluginV2.0.0.20-alpha版发布

allWebPlugin简介 allWebPlugin中间件是一款为用户提供安全、可靠、便捷的浏览器插件服务的中间件产品&#xff0c;致力于将浏览器插件重新应用到所有浏览器。它将现有ActiveX控件直接嵌入浏览器&#xff0c;实现插件加载、界面显示、接口调用、事件回调等。支持Chrome、Firefo…

小琳AI课堂:深入学习BERT

大家好&#xff0c;这里是小琳AI课堂。今天我们来聊聊BERT&#xff0c;这个在自然语言处理&#xff08;NLP&#xff09;领域掀起革命风潮的模型。 出现背景 在BERT之前&#xff0c;NLP领域主要依赖RNN或CNN模型&#xff0c;这些模型大多只能单向处理文本&#xff0c;从左到右…

【全网首创】大模型LLM-RAG知识库问答项目实战课

在大数据和人工智能迅猛发展的今天&#xff0c;大模型和知识库的结合成为了理论探索和实际应用的重要方向。LLM-RAG项目课程正是围绕这一热点展开&#xff0c;旨在通过系统性的教学&#xff0c;帮助学员掌握从项目部署、模块开发到实际应用的完整流程。课程共有43课时&#xff…

SprinBoot+Vue公交智能化系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质…

高可用架构模式

架构里比较重要的是高性能、高可用、高扩展性。上次是高性能&#xff0c;这次是高可用。 对一般的项目而言&#xff0c;高可用主要用公司提供的基建&#xff0c;如多机房部署、主从等。但有些项目确实需要思考更多高可用的事项&#xff0c;如资源不足的情况下要做好限流或者降…

gdb中使用python脚本

1、入门案例 首先有1个a.cpp&#xff0c;代码如下&#xff1a; #include <map> #include <set> #include <iostream> #include <string>using namespace std;struct MyStruct {std::string mName;std::map<int, std::string> mField1;std::set…

SpringBoot3 简单集成 Mybatis plus

SpringBoot3 集成 Mybatis plus 1、引入Mybatisplus的starter <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.7</version></dependency>2、引入数据…

JVM3-双亲委派机制

目录 概述 作用 如何指定加载类的类加载器&#xff1f; 面试题 打破双亲委派机制 自定义类加载器 线程上下文类加载器 Osgi框架的类加载器 概述 由于Java虚拟机中有多个类加载器&#xff0c;双亲委派机制的核心是解决一个类到底由谁加载的问题 双亲委派机制&#xff…