[Interest] How to filter redundant paint call for widget with WA_PaintOnScreen

sivan nanthiran nanthiran2005 at gmail.com
Wed Feb 22 03:44:05 CET 2023


Hi,

I noticed that when a native widget(Qt::WA_NativeWindow) with
WA_PaintOnScreen is added into a vertical splitter, and when the splitter
is moved, 2 paint events will be received for one mouse move.

One paint event is scheduled through
QWidgetRepaintManager::sendUpdateRequest which is from the code path of
processMouseEvent. While another paint event is called straight from
NSView::displayLayer -> handleExposeEvent.

The handleExposeEvent will eventually call QWidget::syncBackingStore while
the posted event of UpdateRequest will also call QWidget::syncBackingStore.
And both of these calls will end up calling PaintOnScreen. Thus 2
paintEvents, for one mouse action.

The problem with this is that since I am handling my own pipeline for
native widget rendering, frequent paint calls within a vsync interval is
exhausting the rendering resources.

I was wondering if I could do something like this. So far this works well
for me. But I would like to know if there is any issue with this approach.
Thanks in advance.

 void QWidgetPrivate::syncBackingStore()

 {

+    if (shouldPaintOnScreen())

+    {

+        Q_Q(QWidget);

+        qApp->removePostedEvents(q, QEvent::UpdateRequest);

+    }

+

     if (QWidgetRepaintManager *repaintManager = maybeRepaintManager()) {

         repaintManager->sync();

     }



     if (shouldPaintOnScreen()) {

         paintOnScreen(dirty);

         dirty = QRegion();

     }

 }



 void QWidgetPrivate::syncBackingStore(const QRegion &region)

 {

     if (shouldPaintOnScreen()) {

+        Q_Q(QWidget);

+        qApp->removePostedEvents(q, QEvent::UpdateRequest);

+

         if (QWidgetRepaintManager *repaintManager = maybeRepaintManager())
{

             repaintManager->sync();

         }



-        paintOnScreen(region);

+        paintOnScreen(region + dirty);

+        dirty = QRegion();

     }

     else if (QWidgetRepaintManager *repaintManager =
maybeRepaintManager()) {

         repaintManager->sync(q_func(), region);

     }

 }

Regards,
Sivan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20230222/0952cb5f/attachment.htm>


More information about the Interest mailing list