Thank you Matt for a very detailed and thorough reply! This is very useful and 
clarifying information.

> On 17 Dec 2018, at 20:39, Matt Jacobson <matthew_jacob...@apple.com> wrote:
> 
> Even if it were, it’s still unsafe to ignore the rect passed to -drawRect:.  
> That’s because the system might require you to redraw a larger area than what 
> your code thinks needs to be redrawn.

Speaking of this, getRectsBeingDrawn: doesn’t seem to work outside of 
drawRect:, e.g. in displayLayer:. Is there any way to get at CA/AppKit’s view 
of what needs redrawn another way? Without this information we’re forced to do 
full updates on every repaint, even when originating from say 
setNeedsDisplayInRect:CGRectMake(50, 50, 10, 10).

>> (I know this is a bad ida, but) is there a way to achieve the same 
>> synchronous flush with layer-backing?
> 
> No.
> 
> The imperative view drawing model you’re describing has long been 
> discouraged.  Among others problems, imperative drawing disrupts the drawing 
> of overlapping views (both siblings and superview–subview pairs), is 
> incompatible with layer-backed views, and prevents system drawing 
> optimizations.

Right. We are aware of the situation. Unfortunately Qt’s Widget module assumes 
an imperative drawing model. 

During AppKit driven updates the flow goes something like this:

        - [QNSView drawRect:] or [QNSView displayLayer:] (depending on whether 
layer-backing is enabled or not)
                - QCocoaWindow::handleExposeEvent(dirtyRegion)
                        - QWidgetBackingStore::beginPaint() 
                        - QWidgetBackingStore::endPaint() 
                        - QWidgetBackingStore::flush()
                                - QCocoaBackingStore::flush()
                                        - a) non-layer-backed
                                                - [view lockFocusIfCanDraw] (if 
there’s no focusView)
                                                - [backingStoreImage 
drawInRect:]
                                                - [view unlockFocus] and 
[view.window flushWindow] (if there was no focusView)
                                        - b) layer-backed
                                                - view.layer.contents = 
CGImageFrom(backingStoreImage)

But when QtWidget drives an update, say after clicking a button, we end up with:

        - Qt’s CFRunLoopSource for posted events
                - QWidgetWindow::event(QEvent::UpdateRequest):
                        - QWidgetBackingStore::beginPaint() 
                        - QWidgetBackingStore::endPaint() 
                        - QWidgetBackingStore::flush()
                                - QCocoaBackingStore::flush()
                                        - a) non-layer-backed
                                                - [view lockFocusIfCanDraw] (if 
there’s no focusView)
                                                - [backingStoreImage 
drawInRect:]
                                                - [view unlockFocus] and 
[view.window flushWindow] (if there was no focusView)
                                        - b) layer-backed
                                                - view.layer.contents = 
CGImageFrom(backingStoreImage)

https://github.com/qt/qtbase/blob/5.12/src/plugins/platforms/cocoa/qcocoabackingstore.mm#L81

A similar situation happens when an animation is driven by a CVDisplayLink, 
where the display-link callback coming in on the secondary thread is delivered 
to the main thread via dispatch_source event handler, so we’re again drawing & 
flushing outside of the display cycle.

https://github.com/qt/qtbase/blob/5.12/src/plugins/platforms/cocoa/qcocoascreen.mm#L270

If we can’t (shouldn’t) do any imperative drawing, should a CVDisplayLink 
callback always just call setNeedsDisplay and let the callback be coalesced 
into the main runloop's display cycle? Even for OpenGL or Metal, where you can 
present a frame imperatively? 

>       • using -[NSImage initWithSize:flipped:drawingHandler] to capture 
> drawing code into a block; by drawing that image in -drawRect:, you’ll defer 
> execution of the drawing code until then

This one looks interesting!

> 
> I hope this helps!

Very much so, thanks again!! 😊 

Cheers,
Tor Arne 

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to