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

sivan nanthiran nanthiran2005 at gmail.com
Fri Feb 24 03:00:48 CET 2023


Hi Tor,

Thanks for the reply. But the ideal situation you are saying is not
possible right? sendUpdateRequest will post an UpdateRequest event which
will end up calling syncBackingstore once the event is processed. On the
other hand, handleExposeEvent will directly call syncBackingStore. These
two can never be coalesced right?

Also, I noticed another issue with my approach. My fix will only work if
handleExposeEvent is called before the UpdateRequest is processed by the
eventloop. But that is not in our control either. Because I don't see
[NSView displayLayer] called directly. It's being called as a result of
other functions like [setNeedDisplay].

Regards,
Sivan

On Wed, Feb 22, 2023 at 6:13 PM Tor Arne Vestbø <Tor.arne.Vestbo at qt.io>
wrote:

> Hi,
>
> Your workaround looks safe enough. Ideally we’d want a situation where sendUpdateRequest
> results in the same callback from the OS as handleExposeEvent, so that the
> two are coalesced, but the machinery for that Is not in place yet.
>
> Tor Arne
>
> On 22 Feb 2023, at 03:44, sivan nanthiran <nanthiran2005 at gmail.com> wrote:
>
> 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
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> https://lists.qt-project.org/listinfo/interest
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20230224/ec8b17db/attachment.htm>


More information about the Interest mailing list