Details
-
Task
-
Resolution: Done
-
P2: Important
-
None
-
None
-
None
Description
Transition from using "Qt Push" to "OS Pull" for update/repaint events on OS X.
"OS Pull" is arguably the correct/recommended way to update on OS X: Paint in response to a NSView drawRect and/or a DisplayLink callback. We want Qt to follow this pattern:
1) Send expose events from drawRect
2) Implement QWindow::requestUpdate() in terms of CVDisplayLink
3) Make QtWigets and QtQuick use QWindow::requestUpdate().
Make QWindow::requestUpdate() / QEvent::UpdateRequest a unified update mechanism for updates and animations on the GUI thread, driven by CVDisplayLink / [NSView drawRect].
Anticipated benefits include:
- AV sync of Qt updates: CVDisplayLink provides a target frame time which can be used for synchronization.
QTBUG-49863 - Improved performance when mixing OpengGL and (raster) widget content.
QTBUG-44228 - Improved correctness for QNSViews embedded in foreign hierarchies: update when an update is required:
QTBUG-45975 - Fix programatic resize issues:
QTBUG-47354,QTBUG-49828,QTBUG-43718 - Handle "backingstore loss" scenarios: https://codereview.qt-project.org/#/c/111175/
Cocoa platform plugin work
Implement the required platform bits to drive UpdateRequest updates, using CVDisplayLink.
Move sending of the initial expose event to drawRect. Also send expose on resize from here. (QTBUG-50414)
Child QWindows
Research topics:
- We should perhaps run the display link for the parent window only
- For raster QWindows content will have been composited on the backingstore for the top-level QWindow. It is desirable to prevent Cocoa from compositing again (select one):
- Child QWindows do not paint: Set NSView isOpaque to false, don't draw anything in drawRect.
- Child QWindows are always opaque and paint their part of the backing store.
Cross-platform Qt Work
Some changes to Qt are required. We'd like to change the existing UpdateRequest handling slightly instead of adding a new event.
- All "update" calls must go to the platform plugin via QWindow::requestUpdate()
- The UpdateRequest must be handled by the QWindow subclass, and the window must produce a frame. This is the only time the QWindow subclass should push a graphics update to the platform plugin [On OS X].
- The platform plugin may send UpdateRequests at any time [while the window is exposed], also when no requestUpdate() call was made.
QTBUG-51915: Change semantics of UpdateRequest events.
Widgets
- The QEvent::UpdateRequest handler should call syncBackingStore(), not repaint(). There is no need to run QWidget::painEvent() code if nothing has changed. This wold make more sense though if UpdateRequest can carry the update rect.
- QWidgetBackingStore::sendUpdateRequest() should call QWindow::requestUpdate(), not post an update event.
- The delayedUpdate functionality can delay via QWindow::requestUpdate()
QTBUG-51914: Make Widgets update/repaint use QWindow::requestUpdate()
QTBUG-4453: QWidget::repaint()
QtQuick
- Drive the basic render loop from UpdateRequest events.
- Drive the threaded render loop from UpdateRequest events, or directly from the CVDisplayLink callback thread.
Pending patches
Rework expose handling: https://codereview.qt-project.org/#/c/143798
Synchronous backing store flush(QTBUG-4453): https://codereview.qt-project.org/#/c/155352/
Other Work
- Qt Quick 2D renderer flicker: https://codereview.qt-project.org/#/c/145971/
Attachments
Issue Links
- depends on
-
QTBUG-43718 Resizing QQuickView causes significant flickering
- Closed
-
QTBUG-51915 Change semantics of UpdateRequest events created by QWindow::requestUpdate()
- Reported
-
QTBUG-51914 Make Widgets update/repaint use QWindow::requestUpdate()
- Reported
-
QTBUG-50414 OS X: Move expose event handling to [QNSView drawRect]
- Closed
- is required for
-
QTBUG-49827 Qt on macOS Graphics/integration update
- Closed