在QML中旋转图像时降低CPU使用情况

Decrease CPU usage while rotating image in QML

本文关键字:CPU 用情 情况 QML 旋转 图像      更新时间:2023-10-16

我创建了一个基于我在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操作的事实。