问题
How to reproduce:
- Run my code
- Keep the mouse over the window that appears
You'll see that CPU usage is fairly high, although it will depend on your hardware. On my PC it's 20% (5% in each of the 4 virtual cores).
My motivation for this testcase: in my real app I have a lot of invisible (culled) items, and while that the culling helps a lot with the CPU usage, it doesn't help as much as I'd expect.
I'd like ideas on why the CPU usage is so high, and how to reduce it.
My code:
main.qml:
import QtQuick 2.5
import QtQuick.Window 2.2
Window {
visible: true
width: 800
height: 500
MouseArea {
width: 1
height: 1
hoverEnabled: true
}
AnimatedItem {
anchors.centerIn: parent
width: 100
height: 100
}
Repeater {
model: 8000
Item {
opacity: 0
layer.enabled: true
width: 1
height: 1
}
}
}
AnimatedItem.qml:
import QtQuick 2.0
Rectangle {
id: root
color: "black"
property real rotAngle: 0
NumberAnimation on rotAngle {
from: 0
to: 360
loops: Animation.Infinite
running: true
duration: 500
}
transform: Rotation {
origin.x: root.width / 2
origin.y: root.height / 2
angle: root.rotAngle
}
}
I've profiled it with the QML profiler, which has shown that insignificant time is spent in QML. So I've also profiled with a C++ profiler (CodeXL). It reports that the majority of time is spent in QSGRootNode::~QSGRootNode()
, due to it calling QSGNodeUpdater::isNodeBlocked(QSGNode*, QSGNode*) const
. I've looked at the Qt source but haven't been able to figure out why it's even calling the former.
回答1:
I found a solution that works at least in the testcase:
Set the parent of culled items to null, then set it back when they're unculled.
In some runs it doesn't help in my real app, but I'm not going to go deeper into this.
回答2:
Save the GPU with visibility:false
Seems you are confused about the visibility thing, opacity:0
is not the same as visible: false
. Just set visible: false
and items won't be rendered, but by leaving opacity at zero, the item not only still renders, but causes blending operations. Make visibility false
and you'll save GPU memory and cycles.
Save the CPU stopping animations
On the other hand, if items are not visible, a good idea is to stop animations, then you save CPU cycles too.
Save CPU and be smooth with Animators
On the other hand, if you must animate them, then prefer to use Animators
and not Animation
s. Animations inform about every change, and Animators do not, so if you do not need to track status, then you save some CPU by using Animators. There is even a specific RotationAnimator.
Go deep and create your own item
Finally, if you have lots of identical items and you must animate them and you are really an optimization junkie (or you are running on embedded) then you should implement a custom QQuickItem and do the animation in a geometry shader.
There are some other more exotic ideas, but you could improve a lot with the above list.
来源:https://stackoverflow.com/questions/44330231/constantly-repainting-a-scene-of-8000-invisible-items-when-a-mousearea-also-exi