Details
-
Task
-
Resolution: Unresolved
-
P2: Important
-
None
-
None
-
None
Description
Qt optimizes memory use for raster child windows by crating a single backing store for the top-level window only. Child windows will then composit on the top-level backing store when painting, possibly invoking the paint functions of the parent window(s) as well.
Cocoa has a similar system, where drawRect is called on views down the hierarchy when updating a region.
We want to avoid compositing twice. There is no need to composit using Cocoa since child and parent window content is already flattened on the Qt backing store.
Available API (NSView)
setNeedsDisplay opaque drawRect canDrawSubviewsIntoLayer
Use cases:
Qt-push: The platform plugin gets a backing store flush call, and can control which view to repaint in response. This is done by calling setNeedsDisplay on the view in question.
OS-pull: Cocoa initiates the update by calling drawRect on a view. The platform plugin has no direct control over which view, but can influence by setting the “opaque” property.
Possible solutions:
1) Child views are transparent and draw nothing. Set the “opaque” property to false for child views and don’t draw anything in drawRect. Invalidate parent views on Qt-push updates.
2) Child wviews are opaque and draw the pre-composited content from Qt. drawRect for parent views are not called. Set the “opaque” property to true and rely on Cocoa not calling drawRect for obscured parent views.
Side note on layers
It makes little sense to have separate layers for child raster windows, since with the shared backing store window content is not independent. We can inform Cocoa this is the case (canDrawSubviewsIntoLayer) and have child window/views redraw themselves using the standard drawRect code path (which can be optimized like described here).
Open questions:
- How is opacity handled on the Qt side? QtWidgets redraws and composits parent widgets. Is the same true for a plain QWindow?
- Option 1) will cause the platform plugin to get multiple drawRect calls for the OS-pull use case. Is this a problem and what can we do about it?
- Option 2) will cause the platform plugin to not attempt to redraw