https://bugs.kde.org/show_bug.cgi?id=503827

--- Comment #1 from nyanpasu64 <nyanpas...@tuta.io> ---
Created attachment 180987
  --> https://bugs.kde.org/attachment.cgi?id=180987&action=edit
Different terminal log of stack traces.

I've done a great deal of debugging about this issue.

- The bugged state is an infinite loop of QQuickImageBase::requestFinished
(std::swap(d->pendingPix, d->currentPix)) → QQuickImage::pixmapChange →
QQuickImage::updatePaintedGeometry → QQuickItem::setImplicitSize(full image
dimensions) → QQuickImage::geometryChange → ...(property bindings)
QQuickImageBase::loadPixmap (d->pendingPix->load(the same image again)).

- The bug does *not* happen if QQuickImage::updatePaintedGeometry operates on a
d->currentPix of size 108x108 (*not* full image dimensions). This translates to
setImplicitSize(108, 108), exactly twice the image item's existing dimensions
of 54x54 (is this a DPI scaling thing? I'm on 1.25x.), which never calls
QQuickImage::geometryChange.

    - I forgot what I did to exercise this test case... maybe lock the screen
with a song playing *then* switch songs?
    - TODO what controls the size of pendingPix/currentPix being loaded?

- If you only play one song, the bug sometimes but not always happens.
- Debugging tip: you can use `loginctl unlock-session 2; sleep 1; loginctl
lock-session 2` to restart the lock screen.

What normally happens?

- The album art is normally set by
OrgFreedesktopDBusPropertiesInterface::PropertiesChanged → ...
PlayerContainer::updateFromMap (this=<optimized out>, map=<optimized out>) at
/usr/src/debug/plasma-workspace/plasma-workspace-6.3.4/libkmpris/playercontainer.cpp:638.
- In one of my runs, `QQuickLayout::updatePolish -> ...
QQuickGridLayoutItem::setGeometry -> ... QQuickItem::geometryChange` loaded the
same image a second time after D-Bus/PlayerContainer set it initially.
    - TODO does this terminate the CPU usage when you wake the screen?

What controls the size of an image being loaded?

- QQuickImage::updatePaintedGeometry() checks d->currentPix->width() and
height(). These come from QQuickImageBase::loadPixmap (d->pendingPix->load(the
same image again)), and the subsequent callback
QQuickImageBase::requestFinished (std::swap(d->pendingPix, d->currentPix)).
    - QQuickImageBase::loadPixmap passes in d->sourcesize. This has width 0,
and height 108 with the UI visible and 1976 with the UI blanked (during the
bug). I wonder if QQuickLayout::updatePolish above sets the size.

With the image hidden, why does QQuickItem::setImplicitSize detect a geometry
change?

- QQuickItem::setImplicitSize() sets d->implicit*, then calls
d->width.setValueBypassingBindings(w) etc. on the input pixmap's size (matching
the album art's size). This should ensure the next call with the same size sees
wDone = hDone = true, returning before the call to geometryChange(). Why does
d->width get set to 0 before the next call?
- If I run `p &(d->width.val)\n (double *) 0x64c7333990f0` and `watch *(double
*) 0x64c7333990f0`, this shows that QQuickItem::setImplicitSize() is setting
d->width = (image width). If I run `fin`, on the same line *without the
function even returning* it sets d->width = 0.
    - Not sure, it appears the first call to geometryChange has some inline
function frames which invoke QQuickItem::setImplicitSize() to 0 (missing in
gdb's bt)?

How many d->pendingPix->load() requests are in flight simultaneously?
- IDK. 1? mpd-mpris only leaves one image in /tmp/mpd_mpris/ at a time, all old
ones are deleted.

How do you prevent this CPU burn incident?
- IDK, maybe don't try to load an image while the UI is hidden?
    - Is this an upstream Qt Quick bug with QQuickItem::setImplicitSize failing
and hitting undefined behavior?
- I don't know how all the QML bindings are arranged that
QQuickImage::geometryChange tries to decode the image again.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to