No description
Find a file
Andros Fenollosa 2c41751831 Metal: render non-GPU frames through the native backend, plus gap fixes
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.
2026-06-04 15:05:59 +02:00
.github/assets README: re-record the sonicboom cursor demo 2026-06-04 11:22:35 +02:00
admin Merge from origin/emacs-31 2026-05-29 11:01:25 +01:00
build-aux Update from Gnulib by running admin/merge-gnulib 2026-05-26 21:57:20 -07:00
cross ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
doc Disable markdown-ts-mode & markdown-ts-view-mode for Emacs 31 2026-06-01 19:11:46 +01:00
etc Support Ansible messages in compilation-mode 2026-06-02 12:43:08 +02:00
exec Fix the Android build again 2026-05-28 11:31:16 +08:00
java Bump master Emacs version to 32.0.50 2026-05-07 17:46:43 +01:00
leim ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
lib Also copy lib/mini-gmp-gnulib.c from Gnulib 2026-05-26 22:21:08 -07:00
lib-src Ignore SO_RCVTIMEO errors in emacsclient 2026-05-31 12:48:42 -07:00
lisp Metal: keep cursor animations alive while Emacs idles 2026-06-04 11:05:21 +02:00
lwlib ARRAYELTS → countof 2026-05-26 21:57:20 -07:00
m4 ; * m4/texinfo.m4 (gl_SET_MAKEINFO): Fix introductory comment. 2026-05-31 14:22:33 +02:00
modules ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
msdos Fix the MSDOS build 2026-05-28 12:59:55 +08:00
nextstep ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
nt Bump master Emacs version to 32.0.50 2026-05-07 17:46:43 +01:00
oldXMenu ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
src Metal: render non-GPU frames through the native backend, plus gap fixes 2026-06-04 15:05:59 +02:00
test Support Ansible messages in compilation-mode 2026-06-02 12:43:08 +02:00
.clang-format
.clangd Tweak .clangd to work with gcc-compiled Emacs (bug#78367) 2025-05-11 11:14:32 +01:00
.dir-locals.el Review some attribute macro usage 2026-03-14 15:08:15 +01:00
.gitattributes Merge branch 'main' into icalendar 2026-02-08 16:05:31 -05:00
.gitignore README: add GPU demos (inline video, animated GIF, cursor effects) 2026-06-04 09:50:51 +02:00
.gitlab-ci.yml ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
.mailmap ; * .mailmap: Add email alias 2026-01-18 21:59:38 +01:00
autogen.sh ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
BUGS
ChangeLog.1 ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
ChangeLog.2 ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
ChangeLog.3 ; Update exported ChangeLog files and etc/AUTHORS 2026-05-07 20:08:43 +01:00
ChangeLog.4 ; Spelling fixes. 2026-04-29 22:45:51 -07:00
ChangeLog.5 ; * ChangeLog.5: Some fixes and tidying up. 2026-05-07 20:14:12 +01:00
ChangeLog.android ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
config.bat Fix the MSDOS build 2026-05-28 12:59:55 +08:00
configure.ac Fase I: split the GPU backend into neutral policy + driver vtable 2026-06-04 08:54:03 +02:00
CONTRIBUTE ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
COPYING
GNUmakefile ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
INSTALL ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
INSTALL.REPO ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
make-dist ; Add 2026 to copyright years. 2026-01-01 12:54:34 +00:00
Makefile.in Restore runtime dependencies to documentation files 2026-06-01 12:15:04 +08:00
README Bump master Emacs version to 32.0.50 2026-05-07 17:46:43 +01:00
README.md README: add GPU demos (inline video, animated GIF, cursor effects) 2026-06-04 09:50:51 +02:00

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):

Inline video

An animated GIF playing next to font-locked code scrolling, all composited by the GPU:

Animated GIF and code

GPU cursor effects (mtl-animations), here the sonicboom mode:

Sonicboom cursor

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.