Fwd: Metal renderer threading issues [macOS]

Philip Race philip.race at oracle.com
Mon Oct 9 19:27:57 UTC 2023


I can't find any Apple docs saying anything like "invoke this only on 
the Appkit thread",
perhaps because you don't have to, but nor do I see any caution about 
using a consistent thread.

The JDK code to start a thread is
- (void) startDisplayLink {
     if (!CVDisplayLinkIsRunning(self.displayLink)) {
         CVDisplayLinkStart(self.displayLink);
         J2dTraceLn(J2D_TRACE_VERBOSE, "MTLLayer_startDisplayLink");
     }
     displayLinkCount += KEEP_ALIVE_INC; // Keep alive displaylink counter
}

and I can see how at least in theory two threads could be calling this 
code at the same time and
so start two threads. Although I'm a bit surprised if macOS doesn't 
detect this internally and
reject it and return an error. And we aren't checking for error returns, 
but in the case of an
error return, I'd really expect that to mean it did not start the thread.

You could try enabling java2d logging to see if we at least have 
matching numbers of
calls to start & stop. But I can imagine that if we've overwritten a 
field holding is the display link thread reference
that CVDisplayLinkStop can't stop that leaked thread.

A relatively simple experiment, that doesn't need JDK would be to just 
call CVDisplayLinkStart N times,
checking return value and then call CVDisplayLinkStop N times (again 
checking return value,
and at the end of it see how many threads are running.

Probably that will tell us we do need to run all these calls on one of 
those 3 threads (AppKit, EDT, QueueFlusher),
although I'm not sure what implementation and performance consequences 
might ensue.

You should file a bug with as much info as you can gather.

-phil.

On 10/8/23 6:52 AM, Alan Snyder wrote:
> I’ve been investigating a problem with a long running application that accumulates an apparently unbounded number of
> CVDisplayLink threads. I do not yet have an explanation or a test case.
>
> The code that creates and releases CVDisplayLinks looks fine, but that assumes there are no threading issues.
> It looks like there are threading issues.
>
> Specifically, it appears that the startDisplayLink and stopDisplayLink methods of the Objective-C class MTLLayer are invoked on multiple threads.
>
> They are invoked on the AppKit main thread from screen sleep notifications and blitTexture.
>
> They are invoked on the EDT from MTLLayer.validate.
>
> They are invoked on the Queue Flusher thread from MTLRenderQueue.flushBuffer.
>
> Perhaps someone familiar with this code could comment?
>



More information about the client-libs-dev mailing list