-
-
Notifications
You must be signed in to change notification settings - Fork 685
Stateful, fast renderer for MMCoreTextView #858
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I haven't had time to look into the PR yet, but thinner text is usually a sign that the font smoothing / subpixel rendering (which is deprecated in Mojave) isn't properly configured. Also, I think we may want to make sure this runs faster than the 10.13 pre-Mojave renderer if we are going to remove that. I have checked out other similar types of renderer before and they don't usually perform faster than the native |
When started from the commandline a new line is output to standard out. The issue mentioned here #796 (comment) was also present in MacVim before. As for performance i am using it on a 4k external Monitor on a MacBook Pro 15-inch 2017 and it seems just as fast as the old renderer if not faster. Obviously this is just my perception if there are any profiling methods let me know. |
If it's going to make fonts look bad (thin, faint) on non-retina monitors, then there should be a preference to turn this new renderer on or off. |
@chdiza I think the bar is this renderer wouldn’t degrade rendering. It’s been on my todo list to take a screenshot and do unit tests against known rendering results but it’s tricky to do it right. |
@chdiza The mystery font rendering change is a bug; I noticed it but haven’t had a chance to track it down yet. Please keep hunting for bugs if possible! @ychin If the performance isn’t good enough, note that my next move will be to use separate movable If performance is an issue with this PR, I could add that now instead of holding off. |
@juliuszint Thanks! I don’t use any plugins that insert images. Now I’ve got one to try. |
Ok - I did find some pretty serious bugs. I normally use Source Code Pro as my main font, but I was messing around with https://github.com/tonsky/FiraCode and Some fairly easy repros:
Then just type like an arrow function:
And you should see some weird rendering bugs and probably a crash or two. If not, try other ligatures like Another thing I noticed, not sure if a bug or not (it appears to be in the previous version too so not a result of this branch, but potentially something that could be fixed here), in insert mode with the |
Found another funky issue with line heights and how they are rendered: It happens on the other side of the powerline, although sometimes doing stuff in the window causes the line to get cropped properly. EDIT: Also been noticing that non native full screen, when activated on my iMac, seems to get stuck in a weird way where the window isn't full screen, but it just renders a blank screen, and I can't interact with it any longer, I have to close macvim completely to recover. I wasn't noticing this on my Macbook Pro, for some reason :/ |
cd315bb
to
475a7b0
Compare
Okay, a bit closer! The new renderer should also be even faster now.
This should now match the current renderer.
This is still an issue in the current patch, but I can work on it soon. It's also partly broken in the old renderer: the icons render OK, but moving the cursor down the column to the right of the icons erases the parts that hang into that column. (Details: The glyphs are wider than a cell but not double-width, so the first cell gets drawn in full (background, then foreground) and then the cell to the right gets drawn in full (background, then foreground). The righthand cell's background is drawn over the glyph. I think the answer is to draw the backgrounds in one pass, then the foregrounds in another pass.)
This should be fixed, want to give it another shot?
The crashes should be fixed, and rendering should now be similar to shipping MacVim, which is also a little bit broken (ligatures may have some parts drawn as individual characters while you edit them). I think the behavior in this PR is close enough to the current state for now, but I have thoughts on how to fully fix it in the future.
Fixed!
I believe this is fixed too, want to give it another try? |
Woots! Giving it a try! |
So non-native fullscreen works when you go into it via |
I've just tried this on Mojave for about 1 minute, and I don't see the NNFS crash that @amadeus mentioned. |
Whoops, never mind. There's the crash! I didn't see it at first because I have S-Cmd-F bound to a VimL function that does some preparatory work before it calls |
I'm hacking on this right now. While exiting full screen,
…but I'm still thinking through it. |
Hey all, mind re-testing? The
|
Just did a little bit of cleanup. I'll leave this PR as a draft until I get some feedback, but otherwise it may be ready for review! |
@s4y is it possible to install this version from pull-request using brew? or it is possible only by building macvim yourself? edit: I've just built it myself (latest MacOS Mojave), renderer works fine! |
@s4y I've been playing a bit with this and I haven't seen the crash yet. There are however some odd visual artifacts when moving in to non-native fullscreen. I think I might have mentioned this before in some other thread, but: I can see, very briefly, a rendering of the contents of the MacVim window intermediate in size between where one starts and the full-blown fullscreen. E.g., I can see very briefly Vim's menubar occupying half of the MacBook's screen width, even though when non in fullscreen it takes up about a quarter and when in fullscreen it takes the whole width. (And curiously, that same menubar is much higher up on the screen during this "flash" than at the start point, enough so that I believe that I should mention this is with |
And… squashed! |
Hi @s4y sorry for the delay but I'm still finding one issue with it. I haven't been able to look closer into why that's the case yet, but I suspect is a bad interaction with the cache:
Other than mostly looks good, but still need to take a closer look at the NSCache implementation. Also, thanks for squashing! I think I wasn't clear and I was hoping we only squash when the entire review is signed off as I wanted to diff the latest changes you did, so for future commits can you only squash in the end? |
@ychin Oof, good catch. I see the problem and I'll try to land a fix shortly. For the moment — unsquashed! |
@ychin re. #858 (comment): I believe this is fixed now! |
@ychin is something left to fix in this branch to launch this renderer at least as a beta? |
@s4y The pull request looks good! Sorry for the delay again. Please squash and I'll merge. One minor issue I found has to do with underline rendering. Right now, an empty space would not get the underline drawn. To see a quick repro, you can do [this is a test](https://github.com/macvim-dev/macvim) The whole "this is a test" line should have underline, but in your change, the spaces wouldn't. I think it's a small bug in I'm ok with merging this without the fix, but it should also be a one line fix. I think we really need better tests for this… Currently I have to go through all known renderer features and make sure they work but after this change merges we should look into better ways to automate this to prevent regressions in the renderer. Thanks for the work and patience! |
src/MacVim/MMCoreTextView.m
Outdated
if (flags & DRAW_TRANSP) | ||
insertionPoint = cell->insertionPoint; | ||
if ([substring isEqualToString:@" "]) { | ||
*cell = (GridCell){ .bg = bg, .insertionPoint = insertionPoint }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to set the other variables such as fg
/flags
/sp
as well to make e.g. underline draw properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
This change reworks `MMCoreTextView` to keep track of the state of the screen instead of drawing to the screen or to an image. This lets `drawRect:` draw any part of the view at any time, as needed. This change came about when the old strategy stopped working: The old strategy calls `drawRect:` for the entire view to handle any draw command from the backend, but drew only the changes on top of the old content of the view. This did not work in new versions of macOS that use layers, because `drawRect:` is now expected to fill the entire rect with new content. If it doesn't, the rest of the view will just contain garbage. bbad3ed worked around this issue by adding an intermediate CGImage which was preserved between draws. This fixed the problem but made rendering slower. With the change, the intermediate image is no longer needed and rendering is much faster overall, which resolves macvim-dev#796. As part of this change, font substitution is now handled by Core Text, which changes which fallback fonts are used in some cases but matches other macOS apps.
@ychin Oh, and…
If you could start documenting the process you go through, I'm very open to helping automate it.
Same to you! |
🙏🙏🙏 |
Alright this is now merged!
Yeah currently MacVim only uses the default Vim unit tests, which aren't enough. I think we need to write up some MacVim-specific As for the process, it's unfortunately been a little ad-hoc, mostly playing with known edge cases like with/without macligatures, fullscreen (two types) modes, East Asian languages, emojis, different styles, composing characters, and so on. And I have a list of characters/lines consisting of an assortment of those that I just paste in and see if it looks correct. But this is why we need to get automated testing going to not have to rely on ad-hoc testing :) |
Updated to Vim 8.2.2127. *Note*: This release doesn't natively support Apple Silicon / M1 yet, but does work under Rosetta. See below. Features ==================== Big Sur / macOS 11 -------------------- - MacVim now has an updated app icon (#1054), and preference pane / toolbars have been updated to match Big Sur's interface guidelines. (#1128) - Fixed Touch Bar warnings when launching MacVim from the terminal. #1114 - SF Symbol characters will show up properly as double-width as most of these icons would take up more than one column. Note that these characters are specific to macOS and would not work in other platforms. #1129 Renderer / scrolling performance improvements -------------------- The Core Text renderer has been rewritten and is now much faster! Scrolling should not stutter and lag like before and generally it should feel a lot smoother now. Thanks to Sidney San Martín (@s4y) for the contribution. #858 With this change, the non-Core-Text renderer is now considered deprecated. The old renderer is accessible either through the Preference Pane (under Advanced) or by setting the defaults "MMRenderer" to 0. It works for now, but it will be removed in a future update as it has known bugs. Menu Localization -------------------- Menus are now localized, see `:h langmenu` for how Vim menu localization works. You can use `set langmenu=none` to turn it off if you would like. #1099 There still exists a few menu items that are not localized, and the general MacVim GUI is not localized as well. If you would like to help, please use #1102 to coordinate with MacVim dev team. Getting help / Help menu -------------------- - Help menu's search bar now searches Vim documentation as well! See #1095. - Vimtutor is now bundled with MacVim, and you can access vimtutor from the Help menu (#1096). There is also a link to the latest release notes as well (#1131). General ==================== - This release does not contain a native universal app for Apple Silicon / M1 Macs yet. The release binary will still work under Rosetta, which should provide enough performance, but if you use Python/etc plugins, you need to make sure you have x86 versions of Python/etc installed (which is still the default for Homebrew as of this release). MacVim is buildable under Apple Silicon, so if you need a native binary, you could build it yourself by downloading the source from the Github repository. See #1136 for progress on releasing a universal app for Apple Silicon. - MacVim has enabled the Github Discussions feature, which serves as a good spot for general discussions and questions. See #1130 and check it out! Fixes ==================== - Launching MacVim from the Dock with locales that use "," for decimal separators now works correctly. #11 (Vim 8.2.1738) - `WinBar` menus (which are used by plugins like vimspector) now work properly and don't create dummy menu items. #918 - Using `:browse tabnew` no longer crashes MacVim in terminal mode. #1107 (Vim 8.2.1842) Misc ==================== - Scripting languages versions: - Python is now built against 3.9, up from 3.8. - Lua is now built against 5.4, up from 5.3. Compatibility ==================== Requires macOS 10.9 or above. Script interfaces have compatibility with these versions: - Lua 5.4 - Perl 5.18 - Python2 2.7 - Python3 3.9 - Ruby 2.7
Updated to Vim 8.2.2127. *Note*: This release doesn't natively support Apple Silicon / M1 yet, but does work under Rosetta. See below. Features ==================== Big Sur / macOS 11 -------------------- - MacVim now has an updated app icon (#1054), and preference pane / toolbars have been updated to match Big Sur's interface guidelines. (#1128) - Fixed Touch Bar warnings when launching MacVim from the terminal. #1114 - SF Symbol characters will show up properly as double-width as most of these icons would take up more than one column. Note that these characters are specific to macOS and would not work in other platforms. #1129 Renderer / scrolling performance improvements -------------------- The Core Text renderer has been rewritten and is now much faster! Scrolling should not stutter and lag like before and generally it should feel a lot smoother now. Thanks to Sidney San Martín (@s4y) for the contribution. #858 With this change, the non-Core-Text renderer is now considered deprecated. The old renderer is accessible either through the Preference Pane (under Advanced) or by setting the defaults "MMRenderer" to 0. It works for now, but it will be removed in a future update as it has known bugs. Menu Localization -------------------- Menus are now localized, see `:h langmenu` for how Vim menu localization works. You can use `set langmenu=none` to turn it off if you would like. #1099 There still exists a few menu items that are not localized, and the general MacVim GUI is not localized as well. If you would like to help, please use #1102 to coordinate with MacVim dev team. Getting help / Help menu -------------------- - Help menu's search bar now searches Vim documentation as well! See #1095. - Vimtutor is now bundled with MacVim, and you can access vimtutor from the Help menu (#1096). There is also a link to the latest release notes as well (#1131). General ==================== - This release does not contain a native universal app for Apple Silicon / M1 Macs yet. The release binary will still work under Rosetta, which should provide enough performance, but if you use Python/etc plugins, you need to make sure you have x86 versions of Python/etc installed (which is still the default for Homebrew as of this release). MacVim is buildable under Apple Silicon, so if you need a native binary, you could build it yourself by downloading the source from the Github repository. See #1136 for progress on releasing a universal app for Apple Silicon. - MacVim has enabled the Github Discussions feature, which serves as a good spot for general discussions and questions. See #1130 and check it out! Fixes ==================== - Launching MacVim from the Dock with locales that use "," for decimal separators now works correctly. #11 (Vim 8.2.1738) - `WinBar` menus (which are used by plugins like vimspector) now work properly and don't create dummy menu items. #918 - Using `:browse tabnew` no longer crashes MacVim in terminal mode. #1107 (Vim 8.2.1842) Misc ==================== - Scripting languages versions: - Python is now built against 3.9, up from 3.8. - Lua is now built against 5.4, up from 5.3. Compatibility ==================== Requires macOS 10.9 or above. Script interfaces have compatibility with these versions: - Lua 5.4 - Perl 5.18 - Python2 2.7 - Python3 3.9 - Ruby 2.7
How to enable this renderer by default? |
I think even having a written list of these would help a ton in the future! (Running through tests manually isn't too bad, figuring out what to test has been the tricky part.) |
@eirnym As I have mentioned before this is the only renderer now. It's always the default. |
Recent change to stateful renderer (macvim-dev#858) has inadvertantly changed how MacVim handles line spacing. Previously, MacVim intentionally ignores the line spacing of a font and creates a new dummy font that essentially has line spacing of 1, but the new code uses the font as is. This means font with non-standard line spacing (e.g. Input Mono) will look different. This is technically the correct way to handle fonts but is different from how MacVim has worked for years. Also, see last time this regression (where MacVim didn't discard line spacing) happened in macvim-dev#928 / macvim-dev#949 which was fixed in macvim-dev#957. Also see macvim-dev#977 where the bug was filed the other way requesting for using the font's line spacing instead of discarding it. This commit re-introduces the behavior to discard line spacing, but only provides it as an option (can be set in the preference pane), while defaulting to using the line spacing as that seems more correct. Note that from a casual survey of other terminals and editors, this behavior is quite inconsistent. Xcode does use the font's line spacing, and was partially the motivation of switching to that as a default. Close macvim-dev#1152.
This change replaces the current rendering paths in
MMCoreTextView
with one which draws from an array of structs that represent the state of each character cell. It applies draw commands to the arrayand marks any touched cells as needing display instead of drawing to a view or image buffer.
In my own tests, this renderer seems to be roughly twice as fast of the current one. Because it seems to work for the use cases of all of the current renderers and reused a lot of code, this PR replaces the other paths instead of adding a preference.
Fixes #796.