The patched rif and terminal hooks are terminal-wide, but only frames the user enabled the GPU backend on have driver data: tooltips, child frames (posframe and friends) and frames created without mtl-enable came up blank. Capture the original NS implementations before patching (gfx_fallback) and delegate every policy entry point to them for frames the driver is not ready on. Verified: tooltip, posframe-style child frame and a second top-level frame all render identically to a pure NS session while the main frame renders through Metal. Also resolved while auditing the display feature matrix: - Underline styles dots and dashes (FACE_UNDERLINE_DOTS/DASHES) were drawn as a solid line; port ns_draw_dash ([segment, segment] pattern anchored at the absolute x so it joins across glyph strings). - :underline (:position N) larger than the descent crossed the glyphs: NS computes the descent as unsigned, so the position underflows and clamps to the row bottom; mirror that clamp. - The internal border was cleared with the frame background; port ns_clear_under_internal_border (internal-border/child-frame-border face, face remapping, top/bottom margins). - With cursor animations enabled the GPU cursor never blinked (blink toggles visibility through erase_phys_cursor, which an overlay never sees): the animation tick now mirrors the window's cursor_off_p and hides the overlay cursor and trail during the off phase. - Before the first cursor draw the overlay used a hardcoded pale tint; fall back to the frame cursor color. No regressions: baseline 141 px and all capture batteries unchanged. |
||
|---|---|---|
| .github/assets | ||
| admin | ||
| build-aux | ||
| cross | ||
| doc | ||
| etc | ||
| exec | ||
| java | ||
| leim | ||
| lib | ||
| lib-src | ||
| lisp | ||
| lwlib | ||
| m4 | ||
| modules | ||
| msdos | ||
| nextstep | ||
| nt | ||
| oldXMenu | ||
| src | ||
| test | ||
| .clang-format | ||
| .clangd | ||
| .dir-locals.el | ||
| .gitattributes | ||
| .gitignore | ||
| .gitlab-ci.yml | ||
| .mailmap | ||
| autogen.sh | ||
| BUGS | ||
| ChangeLog.1 | ||
| ChangeLog.2 | ||
| ChangeLog.3 | ||
| ChangeLog.4 | ||
| ChangeLog.5 | ||
| ChangeLog.android | ||
| config.bat | ||
| configure.ac | ||
| CONTRIBUTE | ||
| COPYING | ||
| GNUmakefile | ||
| INSTALL | ||
| INSTALL.REPO | ||
| make-dist | ||
| Makefile.in | ||
| README | ||
| README.md | ||
emacs-gpu
GNU Emacs with a GPU-accelerated display backend.
On macOS it renders with native Apple Metal: text goes through a GPU glyph atlas, images and inline video are textures, and the whole frame is composited by the GPU instead of CoreGraphics. The output is pixel-accurate against the stock Cocoa backend.
OpenGL support for GNU/Linux and Windows is planned but not implemented
yet. The drawing logic is already platform-neutral (src/gfxterm.c)
behind a small driver interface (src/gfxdrv.h); an OpenGL driver only
needs to implement that interface (src/glterm.c is the documented
skeleton). Contributions welcome.
Status: experimental, under active development.
Note: I am not answering issues for now. Feel free to open them as a public record (they will be read eventually), but do not expect a reply at this stage.
Demos
Inline video playing inside a buffer, decoded by AVFoundation straight
into Metal textures (mtl-video-insert):
An animated GIF playing next to font-locked code scrolling, all composited by the GPU:
GPU cursor effects (mtl-animations), here the sonicboom mode:
Building on macOS
Requires Xcode (or the Command Line Tools) and the usual Emacs build
dependencies (brew install autoconf automake gnutls texinfo pkg-config).
./autogen.sh
SDK=$(xcrun --sdk macosx --show-sdk-path)
CC="xcrun clang" OBJC="xcrun clang" \
CFLAGS="-isysroot $SDK" CPPFLAGS="-isysroot $SDK" OBJCFLAGS="-isysroot $SDK" \
./configure --with-ns --with-mtl
make -j$(sysctl -n hw.ncpu)
The binary is src/emacs (or install the app bundle from nextstep/).
Enabling the GPU backend
Emacs starts with the regular Cocoa backend; switch a frame to Metal with:
(add-to-list 'load-path "/path/to/emacs-gpu/lisp")
(require 'mtl)
(mtl-enable)
Extras once enabled:
(mtl-video-insert "video.mp4" 480 270 t) ; inline video, follows scrolling
(mtl-animations t) ; GPU cursor effects (experimental)
(mtl-draw-stats) ; renderer counters
How it works
redisplay engine (xdisp.c, untouched)
↓
src/gfxterm.c platform-neutral drawing policy
↓
src/gfxdrv.h driver interface (~25 ops)
↓
src/mtlterm.m Metal driver: glyph atlas (CoreText → R8 texture),
render cycle on a persistent texture, AVFoundation
video through CVMetalTextureCache
License
GNU General Public License v3 or later, same as GNU Emacs.


