问题
I'm tyring to figure out how I can accelerate drawing of a QML scene that shows a game map made up of hexagonal tiles. Each tile is a qml item dynamically instantiated via JavaScript on startup. The highlight property of each tile is toggled based on mouse-over movement.
The tile object looks similar to this:
Item {
id: tile
x: // is set to fixed value by JS code on item instantiation
y: // is set to fixed value by JS code on item instantiation
width: // is set to fixed value by JS code on item instantiation
height: // is set to fixed value by JS code on item instantiation
property bool highlight: false
Canvas {
id: background
anchors.fill: parent
onPaint: {
// draw filled hexagon
}
}
Canvas {
id: border
anchors.fill: parent
onPaint: {
// draw hexagon outline
}
}
Canvas {
id: highlightItem
anchors.fill: parent
visible: highlight
onPaint: {
// draw filled yellow hexagon
}
}
}
The issue is that this type of scene is dead slow to render when toggling single tile highlights, with about 11fps at ~300 tiles total in the scene.
If I remove the background and border canvas elements, I am getting more than triple the framerate. I have confirmed that none of the onPaint() methods are called again after the initial paint operation is done.
Below is a QML profiler view of a single highlight event and the time it takes for the signal handler to process. The thin line is where it toggles the highlight property.
Does anyone have ideas why such a simple scene is so slow and how it can be sped up?

回答1:
I guess the bytecode blocks are Canvas.onPaint code which is usual suspect when it comes to realtime rendering bottlenecks.
It really depends on what triggers Canvas.onPaint. This does not happen implicitly, some code must call Canvas.requestPaint() explicitly. Check your code, if that is the case. Maybe that is not necessary.
If some elements have to be repainted every frame, I would suggest to use ShaderEffect. You have to write your rendering code as fragment and vertex shaders, which is very different from canvas API. But it usually orders of magnitude faster.
来源:https://stackoverflow.com/questions/22158605/qml-canvas-performance-issue