Skip to content

Qt GUI burns most of a CPU core repeatedly decoding icons #12758

@nyanpasu64

Description

@nyanpasu64

Operating System Info

Other

Other OS

Arch Linux

OBS Studio Version

32.0.0

OBS Studio Version (Other)

32.0.1

OBS Studio Log URL

https://obsproject.com/logs/ptpJ2CITAoHKvmns

OBS Studio Crash Log URL

No response

Expected Behavior

OBS Studio does not burn a CPU core decoding icons.

Current Behavior

OBS Studio burns most of a CPU core. Samply profiler shows most of it is spent in QStyleSheetStyle::drawControl(QStyle::ControlElement, QStyleOption const*, QPainter*, QWidget const*) const ... QFusionStyle::standardIcon(QStyle::StandardPixmap, QStyleOption const*, QWidget const*) const ... QFusionStyle::iconFromTheme(QStyle::StandardPixmap) const ... QResourceFileEngine::open(QFlags<QIODeviceBase::OpenModeFlag>, std::optional<QFlags<QFileDevice::Permission> >).

Profiler screenshot:
Image

Manual sampling by hitting Ctrl+C in gdb replicated these results; OBS used 60% of my CPU, and two out of four Ctrl+C backtraces were in QFusionStyle::iconFromTheme.

Example backtrace:

(gdb) bt
#0  simdSwapLoop<unsigned short> (src=0x7fffdda75626 <qt_resource_name+6> "", bytes=28, dst=0x555558665750 "q") at /usr/src/debug/qt6-base/qtbase/src/corelib/global/qendian.cpp:825
#1  bswapLoop<unsigned short> (src=0x7fffdda75626 <qt_resource_name+6> "", n=28, dst=0x555558665750 "q") at /usr/src/debug/qt6-base/qtbase/src/corelib/global/qendian.cpp:852
#2  qbswap<2> (source=0x7fffdda75626 <qt_resource_name+6>, n=<optimized out>, dest=0x555558665750) at /usr/src/debug/qt6-base/qtbase/src/corelib/global/qendian.cpp:865
#3  0x00007ffff2d3f941 in qFromBigEndian<char16_t> (source=<optimized out>, count=14, dest=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/global/qendian.h:213
#4  (anonymous namespace)::QResourceRoot::name (this=<optimized out>, node=1) at /usr/src/debug/qt6-base/qtbase/src/corelib/io/qresource.cpp:788
#5  (anonymous namespace)::QResourceRoot::findNode (this=this@entry=0x555555adadd0, _path=..., locale=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/io/qresource.cpp:858
#6  0x00007ffff2d422b9 in QResourcePrivate::load (this=this@entry=0x555557dfdea0, file=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/io/qresource.cpp:339
#7  0x00007ffff2d42b1b in QResourcePrivate::ensureInitialized (this=this@entry=0x555557dfdea0) at /usr/src/debug/qt6-base/qtbase/src/corelib/io/qresource.cpp:389
#8  0x00007ffff2d42f57 in QResource::fileName (this=0x555557dfd0d8) at /usr/src/debug/qt6-base/qtbase/src/corelib/io/qresource.cpp:574
#9  QResourceFileEngine::open (this=<optimized out>, flags=..., permissions=std::optional [no contained value]) at /usr/src/debug/qt6-base/qtbase/src/corelib/io/qresource.cpp:1441
#10 0x00007ffff2d2121f in QFile::open (this=0x555557b7e000, mode=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/global/qflags.h:77
#11 0x00007ffff355b3c2 in QImageReaderPrivate::initHandler (this=0x555557df9570) at /usr/src/debug/qt6-base/qtbase/src/gui/image/qimagereader.cpp:513
#12 0x00007ffff355b6f9 in QImageReader::supportsOption (this=0x7fffffffae00, option=QImageIOHandler::ScaledSize) at /usr/src/debug/qt6-base/qtbase/src/gui/image/qimagereader.cpp:1410
#13 0x00007ffff35145a2 in (anonymous namespace)::ImageReader::ImageReader (this=0x7fffffffae00, fileName=..., size=...) at /usr/src/debug/qt6-base/qtbase/src/gui/image/qicon.cpp:44
#14 QPixmapIconEngine::addFile (this=0x555556112970, fileName=<optimized out>, size=..., mode=QIcon::Normal, state=QIcon::Off) at /usr/src/debug/qt6-base/qtbase/src/gui/image/qicon.cpp:460
#15 0x00007ffff35153b6 in QIcon::addFile (this=this@entry=0x7fffffffb208, fileName=..., size=..., mode=mode@entry=QIcon::Normal, state=state@entry=QIcon::Off) at /usr/src/debug/qt6-base/qtbase/src/gui/image/qicon.cpp:1195
#16 0x00007ffff40384c3 in operator() (prefix=..., icon=..., __closure=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/widgets/styles/qfusionstyle.cpp:3509
#17 0x00007ffff4038e0c in QFusionStyle::iconFromTheme (this=this@entry=0x555555cb8ec0, standardIcon=standardIcon@entry=QStyle::SP_TitleBarNormalButton) at /usr/src/debug/qt6-base/qtbase/src/widgets/styles/qfusionstyle.cpp:3514
#18 0x00007ffff4038e69 in QFusionStyle::standardIcon (this=0x555555cb8ec0, standardIcon=QStyle::SP_TitleBarNormalButton, option=0x7fffffffbcf0, widget=0x55555611c7b0) at /usr/src/debug/qt6-base/qtbase/src/widgets/styles/qfusionstyle.cpp:3538
#19 0x00007ffff3fb2711 in QProxyStyle::standardIcon (this=<optimized out>, standardIcon=QStyle::SP_TitleBarNormalButton, option=0x7fffffffbcf0, widget=0x55555611c7b0) at /usr/src/debug/qt6-base/qtbase/src/widgets/styles/qproxystyle.cpp:380
#20 0x00007ffff3f8c27d in QCommonStyle::subElementRect (this=<optimized out>, sr=<optimized out>, opt=0x7fffffffbcf0, widget=0x55555611c7b0) at /usr/src/debug/qt6-base/qtbase/src/widgets/styles/qcommonstyle.cpp:3074
#21 0x00007ffff4038145 in QFusionStyle::subElementRect (this=<optimized out>, sr=QStyle::SE_DockWidgetTitleBarText, opt=0x7fffffffbcf0, w=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/widgets/styles/qfusionstyle.cpp:3467
#22 0x00007ffff400855b in QStyleSheetStyle::subElementRect (this=0x555555ce9b60, se=QStyle::SE_DockWidgetTitleBarText, opt=0x7fffffffbcf0, w=0x55555611c7b0) at /usr/src/debug/qt6-base/qtbase/src/widgets/styles/qstylesheetstyle.cpp:6402
#23 0x00007ffff3ffb3c0 in QStyleSheetStyle::drawControl (this=0x555555ce9b60, ce=<optimized out>, opt=0x7fffffffbcf0, p=0x7fffffffbcd0, w=0x55555611c7b0) at /usr/src/debug/qt6-base/qtbase/src/widgets/styles/qstylesheetstyle.cpp:4442
#24 0x00007ffff409758e in QStylePainter::drawControl (this=0x7fffffffbcd0, ce=QStyle::CE_DockWidgetTitle, opt=...) at /usr/src/debug/qt6-base/qtbase/src/widgets/styles/qstylepainter.h:51
#25 QDockWidget::paintEvent (this=<optimized out>, event=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/widgets/widgets/qdockwidget.cpp:1633
#26 0x00007ffff3f5d6f3 in QWidget::event (this=0x55555611c7b0, event=0x7fffffffbf40) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qwidget.cpp:9134
#27 0x00007ffff3f020a0 in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x55555611c7b0, e=0x7fffffffbf40) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qapplication.cpp:3307
#28 0x00007ffff2d6a6c8 in QCoreApplication::notifyInternal2 (receiver=0x55555611c7b0, event=0x7fffffffbf40) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1109
#29 0x00007ffff2d6a71d in QCoreApplication::sendSpontaneousEvent (receiver=<optimized out>, event=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1563
#30 0x00007ffff3f4e96e in QWidgetPrivate::sendPaintEvent (this=this@entry=0x5555561c6380, toBePainted=...) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qwidget.cpp:5661
#31 0x00007ffff3f50c27 in QWidgetPrivate::drawWidget (this=this@entry=0x5555561c6380, pdev=pdev@entry=0x555557df9428, rgn=..., offset=..., flags=flags@entry=..., sharedPainter=sharedPainter@entry=0x0, repaintManager=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qwidget.cpp:5611
#32 0x00007ffff3f53a64 in QWidgetPrivate::paintSiblingsRecursive (this=this@entry=0x555555c6ee10, pdev=pdev@entry=0x555557df9428, siblings=<optimized out>, index=<optimized out>, rgn=..., offset=..., flags=..., sharedPainter=0x0, repaintManager=0x555558857670) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qwidget.cpp:5790
#33 0x00007ffff3f51185 in QWidgetPrivate::drawWidget (this=0x555555c6ee10, pdev=0x555557df9428, rgn=<optimized out>, offset=<optimized out>, flags=..., sharedPainter=<optimized out>, repaintManager=<optimized out>) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qwidget.cpp:5652
#34 0x00007ffff3f75929 in QWidgetRepaintManager::paintAndFlush (this=0x555558857670) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qwidgetrepaintmanager.cpp:907
#35 0x00007ffff3f5d0f6 in QWidget::event (this=0x555555f04720, event=0x555555d326e0) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qwidget.cpp:9298
#36 0x00007ffff3f020a0 in QApplicationPrivate::notify_helper (this=<optimized out>, receiver=0x555555f04720, e=0x555555d326e0) at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qapplication.cpp:3307
#37 0x00007ffff2d6a6c8 in QCoreApplication::notifyInternal2 (receiver=0x555555f04720, event=event@entry=0x555555d326e0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1109
#38 0x00007ffff2d6aab2 in QCoreApplication::sendEvent (receiver=<optimized out>, event=0x555555d326e0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1549
#39 QCoreApplicationPrivate::sendPostedEvents (receiver=0x0, event_type=0, data=0x555555aa5c20) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1904
#40 0x00007ffff304db18 in QCoreApplication::sendPostedEvents (receiver=0x0, event_type=0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1757
#41 postEventSourceDispatch (s=0x555555aa5eb0) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:246
#42 0x00007ffff1106f8d in g_main_dispatch (context=0x7fffd8000f60) at ../glib/glib/gmain.c:3565
#43 0x00007ffff1108657 in g_main_context_dispatch_unlocked (context=0x7fffd8000f60) at ../glib/glib/gmain.c:4425
#44 g_main_context_iterate_unlocked (context=context@entry=0x7fffd8000f60, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../glib/glib/gmain.c:4490
#45 0x00007ffff1108865 in g_main_context_iteration (context=0x7fffd8000f60, may_block=1) at ../glib/glib/gmain.c:4556
#46 0x00007ffff304a9d2 in QEventDispatcherGlib::processEvents (this=0x555555aa0c30, flags=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:399
#47 0x00007ffff2d75a86 in QEventLoop::processEvents (this=0x7fffffffcb70, flags=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventloop.cpp:104
#48 QEventLoop::exec (this=0x7fffffffcb70, flags=...) at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qeventloop.cpp:186
#49 0x00007ffff2d6f171 in QCoreApplication::exec () at /usr/src/debug/qt6-base/qtbase/src/corelib/kernel/qcoreapplication.cpp:1452
#50 0x00007ffff3efd31a in QApplication::exec () at /usr/src/debug/qt6-base/qtbase/src/widgets/kernel/qapplication.cpp:2574
#51 0x000055555583d173 in run_program (logFile=..., argc=<optimized out>, argc@entry=1, argv=argv@entry=0x7fffffffda38) at /usr/src/debug/obs-studio/obs-studio-32.0.1-sources/frontend/obs-main.cpp:690
#52 0x0000555555605649 in main (argc=1, argv=0x7fffffffda38) at /usr/src/debug/obs-studio/obs-studio-32.0.1-sources/frontend/obs-main.cpp:1035

Steps to Reproduce

  1. Launch OBS.
  2. (optional) Hide the preview.

Remarkably, even with preview shown, main thread CPU usage is dominated by repeatedly redrawing icons and trying to locate image decoders, rather than displaying video! (I enabled preview and ran a new profiling session, with results indistinguishable from my previous screenshot.)

Anything else we should know?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    ConfirmedThis bug report has been confirmed by project members

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions