ukui-kwin-x11占用cpu 100%

news/2024/6/16 10:29:32 标签: qt, 数据库, 网络, ukui-kwin

1.问题描述

在某些机器上偶尔看到进程ukui-kwin-x11占用cpu使用率100%的情况。

2.期望

在任何机器上不允许看到进程ukui-kwin-x11占用cpu使用率100%的情况。

.问题分析定位

Ukui-kwin最大的一个特点就是支持窗口模糊等等特效,而也就是这个模糊特效要求使得cpu占用率会比不支持窗口模糊特效的情况(或者关闭模特时的情况)明显增高,因为它在维持这种毛玻璃窗口效果时,会持续进行噪点和模糊度绘制。

Ukui-kwin首先得开启混成器,否则任何特效都不支持,开启混成时有两种后端选择方式,分别是OpenGL和XRender,XRender后端支持绝大部分普通特效,但一些高端特效不支持;OpenGL后端支持所有特效,包括窗口模糊、圆角等高端特效。

但并不是所有机器的性能及显卡支持OpenGL作为渲染后端,Ukui-kwin针对机器的显卡以及CPU性能,在开机启动时会做自我检测工作,如果显卡以及CPU性能不够,则不会启动OpenGL后端。

.问题解决方案

为了对性能进行优化,近期我们进行了以下工作。最开始,Ukui-kwin针对机器的显卡以及CPU性能,在开机启动时会做自我检测工作,如果显卡以及CPU性能达不到要求,则直接关闭混成器,这样所有特效都没有了,尤其是无边框窗体的边框自我绘制功能失效,出现黑框的情况,这是不允许的。

3.1 ukui-kwin开机自检不通过,不关闭混成,渲染后端走XRender,代码如下:

bool X11StandalonePlatform::compositingPossible() const
{
    // first off, check whether we figured that we'll crash on detection because of a buggy driver
    KConfigGroup gl_workaround_group(kwinApp()->config(), "Compositing");
    const QString unsafeKey(QLatin1String("OpenGLIsUnsafe") + (kwinApp()->isX11MultiHead() ? QString::number(kwinApp()->x11ScreenNumber()) : QString()));
    if (gl_workaround_group.readEntry("Backend", "OpenGL") == QLatin1String("OpenGL") && gl_workaround_group.readEntry(unsafeKey, false))
    {
        //对于从配置文件中读取的参数OpenGLIsUnsafe为true直接忽略
        fputs("X11StandalonePlatform::compositingPossible,  从配置文件中读取的参数OpenGLIsUnsafe为true直接忽略\n", stderr);
        //return false;
    }

    if (!Xcb::Extensions::self()->isCompositeAvailable()) {
        qCDebug(KWIN_CORE) << "No composite extension available";
        return false;
    }
    if (!Xcb::Extensions::self()->isDamageAvailable()) {
        qCDebug(KWIN_CORE) << "No damage extension available";
        return false;
    }
    if (hasGlx())
        return true;
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
    if (Xcb::Extensions::self()->isRenderAvailable() && Xcb::Extensions::self()->isFixesAvailable())
        return true;
#endif
    if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) {
        return true;
    } else if (qstrcmp(qgetenv("KWIN_COMPOSE"), "O2ES") == 0) {
        return true;
    }
    qCDebug(KWIN_CORE) << "No OpenGL or XRender/XFixes support";
    return false;
}

3.2 3D性能优化

之前,我们在对开启毛玻璃特效后,进行过3D性能测试,开启时比不开启时,3D性能跑分减少约三分之一。

而我们之前开启毛玻璃的开关有两个,一个在Ukui-kwin侧,另一个在主题框架侧,必须2个开关都开启才能使毛玻璃特效生效,后来经过定位分析,主题框架在开启的过程中是针对系统所有应用,经过改进后,我们将主题框架的开关去除,对只有需要支持模糊特效窗口的自研桌面应用采用独自开启的方案方式,使用新方案后3D性能提升46%。

3.3 由于自检测机制并不是万能的,对于个别机器,Ukui-kwin自检测期间,其他桌面应用启动时,在进入QApplication的构造函数时会出不来,出现任务栏和桌面无法完全启动而黑屏的情况,而尤其是不支持OpenGL作为后端的机器居多。

解决方案:将不支持OpenGL作为后端的机器,将其CPU型号和显卡类型进入黑名单记录适配,代码如下:

bool X11StandalonePlatform::adaptCPUPerformance() const
{
    //从系统文件中读取CPU信息
    QFile file;
    QString strCPUInfoList;
    file.setFileName(CPU_INFO);
    bool bRet = file.open(QIODevice::ReadOnly | QIODevice::Text);
    if(false == bRet)
    {
        file.close();
        return false;
    }
    strCPUInfoList = QString(file.readAll());
    file.close();

    //解析CPU信息,提取model name
    QStringList lines = strCPUInfoList.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
    QString strLocalCPUInfo;
    foreach (QString line, lines) {
        if (line.startsWith("model name")) {
            strLocalCPUInfo = line.split(":").at(1).trimmed();
            break;
        }
    }

    if("" == strLocalCPUInfo)
    {
        return false;
    }

    QFile fileConfig;
    fileConfig.setFileName(LOW_PERFORMANCE_CPU_LIST);
    bRet = fileConfig.open(QIODevice::ReadOnly | QIODevice::Text);
    if(false == bRet)
    {
        fileConfig.close();
        return false;
    }
    QString strCPUConfig = QString(fileConfig.readAll());
    fileConfig.close();

    if("" == strCPUConfig)
    {
        return false;
    }

    QStringList lines2 = strCPUConfig.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
    bool bXRender = false;
    bool bBlurDisable = false;
    foreach (QString line, lines2) {
        if("[XRender]" == line)
        {
            bXRender = true;
            bBlurDisable = false;
        }
        if("[blurDisable]" == line)
        {
            bXRender = false;
            bBlurDisable = true;
        }
        if (true == bXRender && strLocalCPUInfo.contains(line, Qt::CaseSensitive)) {
            printf("X11StandalonePlatform::adaptCPUPerformance=======匹配\n");
            //低性能CPU型号判断,如果是低性能CPU则将渲染后端设为XRender
            KConfigGroup kwinConfig(KSharedConfig::openConfig("ukui-kwinrc"), "Compositing");
            kwinConfig.writeEntry("Backend", "XRender");
            kwinConfig.sync();
            return true;
        }

        if (true == bBlurDisable && strLocalCPUInfo.contains(line, Qt::CaseSensitive)) {
            //显卡差,开多了文件管理器就会卡,需去除毛玻璃
            KConfigGroup kwinConfig(KSharedConfig::openConfig("ukui-kwinrc"), "Plugins");
            kwinConfig.writeEntry("blurEnabled", "false");
            kwinConfig.sync();
        }
    }

    return false;
}

bool X11StandalonePlatform::adaptVga() const
{
    QFile file;
    QString strPreDefinePcieInfo;
    file.setFileName(LOW_VGA_PCI_LIST);
    bool bRet = file.open(QIODevice::ReadOnly | QIODevice::Text);
    if(false == bRet)
    {
        file.close();
        return false;
    }
    strPreDefinePcieInfo = QString(file.readAll());
    file.close();

    //获取预定义pcie信息
    QStringList lines = strPreDefinePcieInfo.split(QRegExp("[\r\n]"), QString::SkipEmptyParts);
    QMap<int, int> qMapPreDefinePcieInfo;
    bool ok;
    foreach (QString line, lines) {
        QStringList stringList = line.split(":");
        qMapPreDefinePcieInfo.insert(stringList[0].toInt(&ok, 16), stringList[1].toInt(&ok, 16));
        printf("X11StandalonePlatform::adaptVga===vid:%s pid:%s\n", stringList[0].toStdString().c_str(), stringList[1].toStdString().c_str());
    }


    //根据本机pcie信息遍历匹配预定义信息
    QDir dir(PCIE_DEVICE_PATH);
    if (!dir.exists())
    {
        return false;
    }

    // 遍历PCIE_DEVICE_PATH目录,获取当前PCIE设备列表
    dir.setFilter(QDir::Dirs);
    QStringList busList = dir.entryList();
    busList.removeOne(".");
    busList.removeOne("..");

    foreach(QString bus, busList) {
        QString path;
        QFile file;
        QByteArray charArray;
        bool ok;
        int vid;
        int pid;

        // 读取设备vid
        path = dir.absoluteFilePath(bus + "/" + "vendor");
        file.setFileName(path);
        file.open(QIODevice::ReadOnly | QIODevice::Text);
        charArray = file.readAll();
        file.close();
        vid = QString(charArray).toInt(&ok, 16);

        // 读取设备pid
        path = dir.absoluteFilePath(bus + "/" + "device");
        file.setFileName(path);
        file.open(QIODevice::ReadOnly | QIODevice::Text);
        charArray = file.readAll();
        file.close();
        pid = QString(charArray).toInt(&ok, 16);

        QMap<int, int>::const_iterator iter1 = qMapPreDefinePcieInfo.find(vid);
        if(iter1 != qMapPreDefinePcieInfo.end() && pid == iter1.value())        //找到,并且vid和pid完全匹配
        {
            printf("X11StandalonePlatform::adaptVga=======匹配\n");
            //显卡vid和pid完全匹配,属于低性能显卡
            KConfigGroup kwinConfig(KSharedConfig::openConfig("ukui-kwinrc"), "Compositing");
            kwinConfig.writeEntry("Backend", "XRender");
            kwinConfig.sync();
            return true;
        }
    }

    return false;
}

3.4 经过可以对一些CPU型号和显卡类型记录黑名单,但是无法将所有CPU型号和显卡不适配的型号记录入案。为了彻底解决上述问题,我们修改了系统启动机制,那就是在ukui-kwin在自检测的过程中,不允许其他桌面应用启动,只有在ukui-kwin自检测完以后,才允许其他桌面应用启动,我们通过跟ukui-session-manager进行交互,进行了总体的控制,代码如下:

void X11Compositor::start()
{
    QDBusMessage message = QDBusMessage::createMethodCall("org.gnome.SessionManager",
                                   "/org/gnome/SessionManager",
                                   "org.gnome.SessionManager",
                                   "startupfinished");
    QList<QVariant> args;
    args.append("ukui-kwin");
    args.append("startupfinished");
    message.setArguments(args);

    if (m_suspended) {
        QStringList reasons;
        if (m_suspended & UserSuspend) {
            reasons << QStringLiteral("Disabled by User");
        }
        if (m_suspended & BlockRuleSuspend) {
            reasons << QStringLiteral("Disabled by Window");
        }
        if (m_suspended & ScriptSuspend) {
            reasons << QStringLiteral("Disabled by Script");
        }
        qCDebug(KWIN_CORE) << "Compositing is suspended, reason:" << reasons;
        qCCritical(KWIN_CORE) << "Compositing is suspended, reason:" << reasons;
        QDBusConnection::sessionBus().send(message);
        return;
    } else if (!kwinApp()->platform()->compositingPossible()) {
        qCCritical(KWIN_CORE) << "Compositing is not possible";
        QDBusConnection::sessionBus().send(message);
        return;
    }
    if (!Compositor::setupStart()) {
        // Internal setup failed, abort.
        QDBusConnection::sessionBus().send(message);
        return;
    }

    QDBusConnection::sessionBus().send(message);
    m_xrrRefreshRate = KWin::currentRefreshRate();
    startupWithWorkspace();
}

经过不断的对ukui-kwin性能进行优化后,目前,ukui-kwin版本号>=1.0.1kylin21版本的cpu使用率比较稳定且不高。


http://www.niftyadmin.cn/n/5271292.html

相关文章

【电路笔记】-电容器特性

电容器特性 文章目录 电容器特性1、概述2、标称电容 (C)3、工作电压&#xff08;WV&#xff09;4、公差&#xff08;%&#xff09;5、漏电流6、工作温度&#xff08;T&#xff09;7、温度系数&#xff08;TC&#xff09;8、极化9、等效串联电阻 (ESR) 电容器的特性决定了其温度…

C#编程语言简介

C#&#xff08;发音为C Sharp&#xff09;是微软公司开发的一种现代的、类型安全的、面向对象的编程语言。它于2000年首次亮相&#xff0c;并在随后的几年内迅速发展成为一个广受欢迎的编程语言。C#是.NET框架和.NET Core平台的重要组成部分&#xff0c;这些平台提供了丰富的库…

解决Qt UI界面卡顿的优化方法

以下是一些常见的Qt界面卡顿优化方法: 使用多线程:将耗时操作放在后台线程中执行,避免阻塞主线程。减少界面刷新频率:只在必要时进行界面更新,避免频繁的重绘。使用异步加载:对于大量数据的加载,可以采用异步加载的方式,逐步显示数据,减少界面卡顿感。减少布局计算量:…

【人工智能】实验一:产生式系统实验与基础知识

实验一&#xff1a;产生式系统实验 实验目的 熟悉一阶谓词逻辑和产生式表示法&#xff1b;掌握产生式系统的运行机制&#xff0c;以及基于规则推理的基本方法。 实验内容 设计并编程实现一个飞行生物的小型产生式系统。 实验要求 具体应用领域自选&#xff0c;具体系统名…

Web前端-HTML(简介)

文章目录 1. HTML1.1概述1.2 HTML骨架标签1.3 HTML元素标签及分类1.4 HTML标签关系 2. 代码开发工具&#xff08;书写代码&#xff09;3. 文档类型<!DOCTYPE>4. 页面语言lang5. 字符集 1. HTML 1.1概述 HTML 指的是超文本标记语言 (Hyper Text Markup Language)&#x…

【C++】封装:练习案例-点和圆的关系

练习案例&#xff1a;点和圆的关系 设计一个圆形类&#xff08;Circle&#xff09;&#xff0c;和一个点类&#xff08;Point&#xff09;&#xff0c;计算点和圆的关系。 思路&#xff1a; 1&#xff09;创建点类point.h和point.cpp 2&#xff09;创建圆类circle.h和circle…

Mask-RCNN 分类计数

修改文件&#xff1a; draw_box_utils.py 不希望在绘制的文本周围有白色边界框 可以将以下代码块中的 draw.rectangle 函数调用注释掉或删除掉&#xff1a; draw.rectangle([(left, text_top),(left text_width 2 * margin, text_bottom)], fillNone)改成&#xff1a; fo…

Spring Boot Testing中文文档

本文为官方文档直译版本。原文链接 Spring Boot Testing中文文档 引言测试范围依赖测试 Spring 应用程序测试 Spring Boot 应用程序检测 Web 应用程序类型检测测试配置使用测试配置主方法排除测试配置使用应用程序参数使用模拟环境进行测试通过运行中的服务器进行测试自定义 We…