Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
5.10.1, 5.12.1
-
None
-
Qt Creator 4.8.2, MacBook Pro Retina (2014) and MacBook 12 (2017) on macOS 10.14.4
Description
In my audio application I am trying to continuously update a widget that is part of a custom QDockWidget (peak meter). Think of the Qt demo application "Audio Input Example", just encapsuled in a dock widget. On Windows this is working perfectly fine (CPU load <1% on the same machine). But on macOS it is causing a serious performance impact (10%-95% depending on MainWindow size and CPU power).
This is probably a bug. Any help is appreciated. See my investigations below.
I've built this basic example in order to reproduce this issue (see attachment):
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDockWidget> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connect(&m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); m_timer.start(30); m_projectsDock = new QDockWidget(tr("Test"), this); addDockWidget(Qt::LeftDockWidgetArea, m_projectsDock); } MainWindow::~MainWindow() { delete ui; } void MainWindow::onTimeout() { m_projectsDock->update(); }
I've already profiled the application. It seems like the complete background (backing store) is copied every time an update is issued.
void QImage::detach() { if (d) { if (d->is_cached && d->ref.load() == 1) QImagePixmapCleanupHooks::executeImageHooks(cacheKey()); if (d->ref.load() != 1 || d->ro_data) *this = copy(); if (d) ++d->detach_no; } }
Somehow d is refereced more than once.
Heaviest Stack Trace:
32 6150.0 PerformanceTest (12139) :0 31 6147.0 Main Thread 0x33d05 :0 30 libdyld.dylib 6147.0 start 29 PerformanceTest 6147.0 main PerformanceTest/main.cpp:10 28 QtCore 6147.0 QCoreApplication::exec() 27 QtCore 6147.0 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) 26 libqcocoa.dylib 6147.0 QCocoaEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) 25 AppKit 6147.0 -[NSApplication run] 24 AppKit 6147.0 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] 23 AppKit 6147.0 _DPSNextEvent 22 HIToolbox 6147.0 _BlockUntilNextEventMatchingListInModeWithFilter 21 HIToolbox 6147.0 ReceiveNextEventCommon 20 HIToolbox 6146.0 RunCurrentEventLoopInMode 19 CoreFoundation 6144.0 CFRunLoopRunSpecific 18 CoreFoundation 6087.0 __CFRunLoopRun 17 CoreFoundation 6067.0 __CFRunLoopDoSources0 16 CoreFoundation 6066.0 __CFRunLoopDoSource0 15 CoreFoundation 6066.0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ 14 libqcocoa.dylib 6047.0 QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void*) 13 libqcocoa.dylib 6047.0 QCocoaEventDispatcherPrivate::processPostedEvents() 12 QtCore 6047.0 QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) 11 QtCore 6047.0 QCoreApplication::notifyInternal2(QObject*, QEvent*) 10 QtWidgets 6047.0 QApplication::notify(QObject*, QEvent*) 9 QtWidgets 6047.0 QApplicationPrivate::notify_helper(QObject*, QEvent*) 8 QtWidgets 6046.0 QMainWindow::event(QEvent*) 7 QtWidgets 6046.0 QWidget::event(QEvent*) 6 QtWidgets 6046.0 QWidgetBackingStore::doSync() 5 QtGui 5658.0 QBackingStore::beginPaint(QRegion const&) 4 libqcocoa.dylib 5657.0 QRasterBackingStore::beginPaint(QRegion const&) 3 QtGui 5588.0 QPainter::begin(QPaintDevice*) 2 QtGui 5578.0 QImage::detach() 1 QtGui 5578.0 QImage::copy(QRect const&) const 0 libsystem_platform.dylib 5577.0 _platform_memmove$VARIANT$Haswell