fix(qbz-qt): rasterize every Canvas on the GUI thread

The owner hit a segfault after clicking around. Cooperative and Threaded
rasterize on the scene-graph RENDER thread, and RoundedImage is instantiated in
25 files — every card, row and queue row — so list recycling creates and
destroys hundreds of these while async artwork callbacks schedule repaints on
them. The render thread can be mid-draw on a pixmap whose Canvas is already
gone. The ambient field makes it worse by repainting 30 times a second for the
whole window lifetime on that same thread.

Immediate keeps paint and destruction on one thread. renderTarget: Image
already meant CPU raster, so nothing looks different.

Not yet confirmed on hardware: the decisive check is running the previous
binary with QSG_RENDER_LOOP=basic, which gives Cooperative no separate thread
to race with. If that survives the repro and the default loop does not, this is
the cause.

cc
This commit is contained in:
vicrodh committed 2026-07-28 16:22:19 -06:00
1 parent 31b1484c01
commit b580fdafad
3 files changed
+15 -3

No files matched your search

+4 -1
View File
@@ -45,7 +45,10 @@ Canvas {
: true
renderTarget: Canvas.Image
renderStrategy: Canvas.Cooperative
// See RoundedImage.qml. This one repaints 30x/s for the whole window
// lifetime, so it is the canvas most likely to be mid-raster when another
// is torn down on the same render thread.
renderStrategy: Canvas.Immediate
// The shader clock (t = time * 0.75). Accumulated at ~30fps.
property real t: Math.random() * 40.0