bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#63187: 30.0.50; Tail of longer lines painted after end of nearby lin


From: Alan Third
Subject: bug#63187: 30.0.50; Tail of longer lines painted after end of nearby lines on macOS
Date: Sun, 25 Jun 2023 19:17:04 +0100

On Sun, Jun 25, 2023 at 01:07:19PM -0400, Aaron Jensen wrote:
> 
> Thank you for the continued explanation. I'm doing some additional
> digging and it's making me wonder if what we are doing is even
> possible reliably with Cocoa drawing and without any synchronization
> primitives like MTLCommandBuffer's waitUntilCompleted. If I understand
> correctly, we do something like this:
> 
> 1. Draw to Surface 1 (buffer commands)
> 2. Assign Surface 1 to the view as its layer
> 3. Copy from Surface 1 to Surface 2
> 4. Copy rects on Surface 2 to other parts of Surface 2

Yep.

> As I understand, there's no way to ensure that all commands have been
> flushed all the way to the point that we know that Surface 1 is
> actually representative of the commands we have sent it.

No, you can use [NSGraphicsContext flushGraphics] and CGContextFlush
to force it.

As I recall we've tried that in both copyRect and display.

Ultimately releasing the context will have to flush any buffered
writes, if it didn't then this would be a widely known problem as
practically nothing graphical could be relied upon.

This is my point about why I can't see this being the issue. Although
it looks like it explains what we're seeing, we would have to be
hitting some extreme edge-case.

> I came across some notes from the Chromium team:
> https://www.chromium.org/developers/design-documents/iosurface-meeting-notes/
> 
> They (as of the notes) decided not to double buffer and just write
> directly to the one surface. I don't know if that's reasonable/viable
> for Emacs or not.

Set CACHE_MAX_SIZE to 1.

But on my machine this resulted in unacceptable rendering flaws on
almost all animated gifs as partially drawn buffers were sent to VRAM.

And adding more open frames just made it worse, as I recall. I never
really understood why.

It wasn't just gifs, but they were an easy test.

But then, I'll bet performance is incredible. ;)

> Lastly, as an aside, if we *could* synchronize, would it be more
> efficient to not copy the entire surface just to then copy rects again
> to handle scrolling? I can imagine this would add more complexity than
> is worth it, I'm mainly asking for my own edification.

I'm not sure if I'm following your question correctly, but yes, not
copying is usually going to be faster, but it depends how long it
takes the buffer to copy to VRAM, you might well find that you're
waiting for it to finish when you may have already been in the
position to start drawing to a second buffer.

In theory, if you set CACHE_MAX_SIZE > 1, and change

    [cache addObject:(id)currentSurface];

to

    [cache insertObject:(id)currentSurface
                atIndex:0]

It should try to pick up the most recent surface first, then
copyContentsTo will recognise that it's the same surface as last time,
and not bother with the copy. I think you'd have to enable

    [self setContents:nil];

to work all the time too, as you might be wanting to "replace" the
contents layer with itself.

I've no idea if that would really work. IIRC on my machine the surface
that was "in flight" to VRAM was never done fast enough that it would
be picked up by the next getContext call so I felt it was a waste to
check it every time. (And in fast-scrolling situations I could have as
many as three surfaces in-flight at once if I let the cache grow that
big.)
-- 
Alan Third





reply via email to

[Prev in Thread] Current Thread [Next in Thread]