在QML中旋转图像时降低CPU使用情况
Decrease CPU usage while rotating image in QML
我创建了一个基于我在Mac OS X和Windows上部署的Qt 5.2
的QML应用程序(从XP到8)。我的应用程序有一个主动画,该动画在用户播放时无限期地旋转图像。该动画是应用程序的核心部分,我无法将其删除。
旋转图像需要过多的CPU功率,我正在寻找一种解决此问题的方法。其背后的原因是,用户的 lots 不支持OpenGL 2(在Windows上),我将不得不依靠Mesa的DLL来执行软件的渲染,从而在这些机器上无法使用该应用程序,而该应用程序在这些机器上无法使用。动画正在运行。
这是我当前对QML中动画的实现:
Image {
id: imgBroadcastState
source: "images/broadcast_button.png"
anchors.horizontalCenter: parent.horizontalCenter
NumberAnimation on rotation {
from: 0
to: 360
running: rootWindow.isBroadcasting
loops: Animation.Infinite
duration: 7000
onRunningChanged:{
if(!running) {
imgBroadcastState.rotation = 0;
}
}
}
}
我尝试的第一个解决方案是创建一个巨大的精灵,其中包含我的动画框架,然后加载了动画。这减少了CPU,但显然还不够,超过了RAM消耗的两倍,最大300MB,这对于旧的Windows XP机器来说不是一个好的解决方案。
我还尝试了子分类qquickpainteditem,并每30ms(使用QTimer
)手动调用paint()
旋转图像。这也降低了CPU,但也不够。这是我使用的代码:
void MXPaintedItem::paint(QPainter *painter)
{
QTransform rot;
rot.rotate(m_angle);
painter->setRenderHint(QPainter::Antialiasing);
painter->setRenderHint(QPainter::SmoothPixmapTransform);
painter->translate(width() / 2, height() / 2);
painter->rotate(m_angle);
// Use preloaded QImage
painter->drawImage(QPoint(-width() / 2, -height() / 2), m_image);
m_angle += 2.5;
}
有什么方法可以改进并减少旋转动画的CPU使用情况?
编辑:
当然,我可以更改动画或不使用动画,但这不是长期解决方案。最后,必须动态绘制/更新此图像以反映Vumeter并表示声音级别。因此,我需要找到一个适当的解决方案,允许我实时更新QML视图的一部分,而无需重新绘制整个UI并采用这么多CPU。
edit2 :我发现主要CPU的使用不是旋转本身,而是它每次都必须重新绘制整个UI的事实。您可以通过在paint()
功能中调用return
而不是旋转任何内容来确保这一点。与对图像本身进行动画化相比,CPU的使用情况与此相同,这表明该问题来自每次场景中的QML组件都会更新整个UI
如果您的内存空间且旋转次数很少,请为每个旋转使用一个位图。自计算机开始以来,这就是"旋转器"的写作方式。
理论是,一个比特框比执行旋转转换的速度更快,然后打击所得图像。
接下来,我将尝试使用您的动画并制作动画GIF。无论您使用什么工具来生产GIF,都应为您提供配置压缩/优化的能力,以获得您满意的质量/尺寸。
然后尝试使用QML AnimatedImage元素显示GIF,也许会提供更好的结果。
在研究更多之后,我得出的结论是没有简单的方法来优化它。最好的性能将通过QML本身获得,因为它已针对缓存元素进行了优化和改善现场重新粉刷。
主要解决方案是仅重新涂上场景的一部分。QML和新的场景图渲染不可能,并且在不久的将来没有计划。负责此功能发展的人在QT中给了我这个答案。
CPU用法本身的出现高度取决于硬件和图形卡驱动程序,因为现在所有内容都基于OpenGL 2.0,并且依赖于您的硬件/驱动程序正确支持某些OpenGL操作的事实。
- 用C++中的一个变量定义一个常量
- 用c++从输入文件中读取另一行
- 用C++20 fmt限制结果的总大小
- 在Windows上用C++裁剪HBITMAP
- 用c++阅读音频
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 试图在visual studio上用C++创建一个桌面应用程序
- 用C++在单独的头文件中完成函数体
- 用C++中的sscanf赋值
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 用MacOS Mojave编译C++:致命错误:mpi.h:没有这样的文件或目录
- 是否可以用"iostream"包装现有的TCP/OOpenSSL会话
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 从父数组测试用例构造二叉树失败
- 用C++将哈希表写入文件并从文件中恢复
- 如何让我用C++编写的图形程序使用GPU而不是CPU进行渲染
- 为什么我的程序设计为用完 RAM 和 CPU 不使用所有 RAM 和 CPU?
- 避免 CPU 争用