Hacker News new | ask | show | jobs
I built a GPU back end for Emacs (en.andros.dev)
190 points by andros 3 days ago
26 comments

Emacs user for >32 years now. It's a pity this won't get merged. There is a big usability/accessibility factor to consider here: I really wish I could have something like the Ghostty cursor_blaze.glsl shader for highlighting where the cursor is when you switch windows/buffers/apps.

Most people think GPU equals silly toys like video in a text window, but there is much more to it than that.

[and yes, I know about beacon, which unfortunately doesn't work too well, as well as about pulse, which I use]

GPU speedups are welcome, but you don't need a shader and a gpu to insert a flashy effect.

Emacs has had this for decades: `pulse.el`. And building your own is very simple also.

You'll still need someone to write the glue code to trigger the pulse, but then a gpu patch on the backend wouldn't give you that either.

I'm sure someone on MELPA/Github has written code to do just this already.

I expected this kind of reply, which is why I specifically mentioned that I actually use pulse.

This attitude of "Emacs already has this" is not helpful and limits the development and evolution of Emacs. Have you seen how the Ghostty shaders work and how specifically the cursor highlighting one works? It is way better than what Emacs does today.

> Emacs has had this for decades

Pulse works, but honestly it pales when compared to neovim's effect. It would be nice to have a machinery to create things like that in Emacs.

I would love to have something like nvim's "smear-cursor". iirc someone wrote a patch (it was posted on r/emacs) - I'll attach it if I find it. My first thought was "is it doable as a dylib?"
The feature is LLM generated, and also doesn’t bring any speed ups, only slowdowns
Did you read the article to the end? It does bring speed ups for high resolution, like 4K. It's at more conventional laptop display sizes that its roughly on-par with, but the GPU scales better with pixel count.
Only on Linux it seems. The fact that it makes rendering slower on lower resolution is a big concern.

I’m all for speeding up Emacs as a long time user, but I share emacs maintainers stance on not accepting llm code.

I'd be thrilled with a second thread much less GPU.
I don't think video in a text window is a silly toy. Sounds like another useful tool in the toolbox.
https://github.com/tanrax/emacs-gpu/blob/main/.github/assets...

This massive speed-up on 4K screens makes me want to try it. The wayland pgtk version has such terrible latency I have to use the X11 build to avoid gnashing teeth during my working hours. And I think it's the X11 version that uses cairo, so the actual speedup in my case might be even larger.

I reported the issue years ago, the pgtk maintainer confirmed, say they can't do much as they're using GTK3 which isn't hardware accelerated, so I have to wait until they migrate to GTK4 (in a decade or so). A bit disappointing, but that's open source.

Looks like I'm not the only one suffering with a 4K screen: https://old.reddit.com/r/emacs/comments/ucv0at/awful_perform...

Good news on the Wayland front: there is already a working branch (wayland-pgtk-backend) that adds a PGTK binding on top of the same EGL/GLES driver, pending merge to main. If you want to try it before that, the branch is available on the repo.
I can't find that branch here - https://cgit.git.savannah.gnu.org/cgit/emacs.git

Am I looking in the wrong place?

https://github.com/tanrax/emacs-gpu/tree/wayland-pgtk-backen...

The main emacs-gpu branch doesn't have wayland support.

Oh thanks! I thought they meant this was going on in the real emacs man.
My experience with Emacs, 4K and Wayland was so abysmal that I spent a weekend making my config fully compatible with a terminal.

Not ideal, but I'll keep running it through Ghostty until it's fixed.

I have been using only 4k monitors in Linux, with X11 (and XFCE) for more than a decade.

During the years, I have used a great number of text editors, e.g. vim, jedit, kate, geany, Visual Studio Code, neovim, etc.

Only this year I have switched to emacs, because it is more suitable for certain customizations that I prefer (for scripting, I like more Emacs Lisp than alternatives like Lua).

I have seen no performance problems (in GUI mode, I do not use it under a terminal emulator). On my hardware (with NVIDIA GPU) it is at least as fast as any other text editor that I had been using. Certainly much faster than Visual Studio Code.

As a terminal emulator I am now using ghostty, after previously using kitty and many other terminal emulators more distantly in the past, so GUI performance is important for me.

Ghostty seems faster than Emacs, so I believe that switching to GPU text rendering could accelerate Emacs, but for a significant speedup a more complete redesign of the graphics output would be necessary than in the parent article.

The problem is that this might be easy only when targeting a single GUI environment, but that would be in contradiction with the original Emacs goal, to be usable under many operating systems and GUI environments.

Just switch to X11. Wayland is never going to work.
Use the x11 build. It’s night and day
I didn't notice to much performance issue switching to PGTK on an ultrawide on Niri. Are you using the daemon to render Emacs as a client?
I have perf issues with emacs-pgtk on a 4k screen on Wayland with Niri in both Emacs as a client and not. The issues appear with typing or scolling, the delay and lag become noticeable.

For me the issue is only unbearable when running fractional scaling, for some reason.

I'm going to try the branch mentioned in the sibling comment, though.

I have almost the exact same setup as you and even have strange behavior with fractional scrolling. I'm on NixOS so the setup is even inspectable: https://codeberg.org/arik/dotfiles

After resetting the scale from 1.2 to 1.0 through 'niri msg output HDMI-A-2 scale 1' I actually noticed a performance increase! I will have to troubleshoot this, although you may have stumbled on a great lead toward the root cause.

Also on Niri with fractional scaling and pgtk. IIRC the issue here is that for programs that don't support wp_fractional_scale, compositors deal with this by rendering at the next highest integer factor, and downscaling it down to achieve the desired factor. This is much, much worse for Emacs since it uses GTK3 and doesn't support hardware acceleration with Cairo, at least according to Po Lu [1] so you're effectively rendering via CPU at a very high resolution.

For XWayland apps Niri just renders at the native resolution (ignoring scaling), meaning a decent workaround is to use the Lucid/non-pgtk version and manually scaling up the UI. Unfortunately I go from scaling at 1.25 on my screen to 1.00 on my external monitors, which means I can't use the non-Wayland versions without messing up the font size on either my desktop and monitor.

[1] https://mail.gnu.org/archive/html/bug-gnu-emacs/2024-09/msg0...

I'm also on Emacs and Niri, seems to be a popular combo, and I don't have any performance problem.

At home I'm driving an Ultrawide (3440x1440@75Hz) at scale 1.1.

At work I'm driving two 4k screens at scale 1.2.

I might be less sensitive to latency but it could also be a graphics driver issue or something similar. I'm using Arch with emacs-wayland (pgtk) with a strix halo (all AMD) laptop.

It might also just be the case that the hardware you have is good enough that the lag isn't noticable.

You should still be able to notice a spike in CPU usage whenever you force Emacs to redraw the frame by typing into it though.

I didn't invent this mitigation FWIW - I saw it mentioned in one or another thread about this by someone else - possibly on the big reddit thread on this topic, not sure.
Just switch to xlibre.

Wayland is a dead end.

Aside from the wonderful contribution to Emacs, I have the utmost respect for how straight-forward you were with the 100% LLM generated code. The enlightening conversation on GPU freedom that ensued was also informative.
This is a way of using LLMs that doesn’t seem appreciated enough: prototyping a refactor or other new approach to see how it goes. Even if you then rewrite it from scratch, it’s a big timesaver because you’re using the new knowledge to do the “right thing” and avoid backtracking.
This is exactly how I use LLMs. "I wonder if it's possible to ...", and if I get something that seems to work or passes the test suite that gives me lots of added confidence that an approach is worth spending proper engineering time on.

Or sometimes you get suggested a method or library you've never heard of, opening your horizons.

I completely agree with you. For me, it was the best reward.
Well done. Here’s hoping that a hand-written GPU backend gets developed based on this wonderful proof of concept. There’s no reason to not take advantage of the state of the art hardware when it’s available. And screens are only moving toward 4k and higher (6k or 8k).
Or that GNU updates a policy that will very rapidly go from probably net silly/mildly contestedly useful to completely ridiculous in a year or two. Not allowing LLM code will be basically turning down the work of the worlds best programmers running at 50x speed in couple years, and will functionally doom any software project that enforces such a policy.
The problem is that some GNU packages, Emacs among them, have a policy that copyright of the code must be assigned to the FSF. This policy exists because the FSF and GNU have gotten legal advice to the effect that all owners of a project must sue together to sue against copyright violators. So I don't forsee this policy changing while LLM output is not copyrightable.
Doubt that. If you couldn’t write it yourself you can’t get an LLM to do it for you. So unless you’re attracting the 50 best software developers you’re getting middling to miserable results.
We shall see.
that policy should only ever be relaxed towards legacy contributors and those they can vouch for.

otherwise, allowing sloptributions opens the gates to a myriad you-know-who who used to submit pull requests for ESL rewrite of two sequences in README.md and now submit chatgpt-generated refactors - which waste even more human time - just so they can proudly put "open source contributor" on their resumes.

Me too. In the meantime, I'll stick with this version :)
could've guessed staying away from xdisp.c was a good idea, cf. the "Buttery Smooth Emacs"[0] post:

> Keep in mind that Emacs xdisp.c tries to support five different toolkits (including two different major versions of GTK) with #ifdefs. There is no runtime abstraction. We define three or four different versions of each damn function. It’s a nightmare.

[0] https://gist.github.com/ghosty141/c93f21d6cd476417d4a9814eb7...

"No runtime abstraction" seems the correct approach for good performance.

Run-time abstractions should always be avoided when the problem can be solved at compile-time.

While the conditional compilation syntax of the C/C++ preprocessor is not nice, good programming text editors can make it much more readable, by highlighting/hiding appropriate text sections.

I know this type of approach was rejected at the beginning, but you can also just ask CoreGraphics to use the GPU for 2D rendering (and I'm sure there are equivalent paths in e.g. Skia or Cairo).

On macOS/iOS, the easiest way would probably be to set the drawsAsynchronously property on a CALayer. Then, all CoreGraphics operations on the context passed back to the layer via drawInContext: will be GPU accelerated.

Lastly, there are some pretty sharp edges to this API, so definitely don't go flipping it on for every layer/view in your view hierarchy.

There's a lot to discuss here, a very interesting comment. I wouldn't want to talk too much publicly about certain technical elements, and because I don't want to encourage solutions decided by LLMs, however the Skia/Cairo-GL angle is interesting but would be a heavy dependency and does not help Linux, where the same gfxterm.c policy drives the OpenGL backend. The vtable abstraction was specifically designed so the rendering logic is written once and the platform just supplies the draw primitives.
This seems like the "obvious" solution. Why was the rejected?

EDIT: It appears to be an objection to GPU programming entirely.

In case anyone is curious, ezemtsov (EWM author) has a Skai port of Emacs [1] built for Wayland (only).

[1]: https://codeberg.org/ezemtsov/emacs

"That was the moment the architecture stopped being a promise and became a fact."

The post is AI generated as well, right?

it certainly has the tells... I could be charitable and say maybe since it's a bilingual blog it was generated as a type of translation from the original source, but that post itself seems only available in English
If I were you, it'd be pretty much worth it when you had a conversation with Stallman.
Hey @d12frosted, would it be possible to have it as the emacs-plus (homebrew formula) option?
Great work! Possible to have a patch that I can apply on 32.0.5 and try this out?
Yes, of course, I worked with the develop version until at a certain point I decided to downgrade to the stable versions. I'll be releasing more versions later; I'm still focused on fixing minor issues in Linux.
Andros is also the guy behind the really cool Org Social:

https://org-social.org/

That's me!
Wow, I was just looking for something like this 15 minutes before you posted! Seems to not support Wayland though, from a quick scan, but cool project nonetheless
Interesting improvement. My biggest issue with Emacs and the reason that I left it was because it was not multi-threaded. I wonder if is/can be multi-threaded now.
You have libraries for multithreading. I use them myself for parallel tasks. However, how events and redrawing work is a completely different matter.
Concurrency is a source of many bugs and complexity. Emacs have a few async mechanisms and they’re good enough for most tasks. The async nature of other editors does not really matter as you’re still waiting for actions to complete.
> because it was not multi-threaded

I'm honestly curious, what kind of multi-threading you use, in whatever you're using now instead of Emacs? Can you share some practical example(s)? I'm not trying to trick you, I'm just curious for what kind of complex tasks possible there and where Emacs comes short.

The main one was C++ intellisense on a large codebase. It felt unusable due to the single threaded bottleneck. Mind you, this was a decade ago or more by now.
I fetch my google calendar every few minutes to get everything into my agenda. The API request is async, but writing to the calendar file and some additional processing made Emacs hang for 10 seconds at a time. The LLM-inspired solution was to spawn entire new emacs processes to do the work in the background. It's pretty cool that it works, but it feels like it shouldn't - and wouldn't with 2+ threads - have been that complicated.
Ah, so for stuff like that, it seems current strategy is to build a "server" part that handles concurrency (in a different language) - that's how lsp servers work, and projects like eca-emacs. If I ever get to build something like what you've described I'd probably write the server part in Clojure, Janet, Jank or Jolt¹ or maybe even Zig or Rust. It is a nice, practical example - exactly the stuff I've been asking about, thank you for providing it. I agree, it would be nicer if this kind of stuff was possible without complicated hacks.

---

¹ https://github.com/jolt-lang/jolt

Curious that your comment was dead for whatever reason. I vouched for you because I'm also curious at what a user would need concurrency for in a text editor (I mean, granted, Emacs is a Lisp implementation with an amazing text editor attached so in theory someone may want concurrency for programming something in Elisp).
To avoid UI freezes, separate event processing from rendering (for example). It's very common to see the interface freeze while a complex command is running.
This is a really cool project. And it's so small, too, when you consider what it unlocks and the opportunities it creates.

Really awesome!

I tried to look for the thread on the emacs-devel archive, and couldn't find it. Is it not archived for some reason?
I'm more impressed that you managed to stream youtube - that seems to me like almost the more impressive feat.
There's not much of a secret here; I used ffmpeg to pre-download the video—there's... no actual streaming. When you select a video, it downloads in parallel and starts playing. Sorry to disappoint you :)
This is the way! Very nice work. I want it!
Thank you!
This should also compile to WASM, and support WebGPU, not that I’m advocating for it.
Doesn't just emacs render to a tty?

Or is this for some Emacs build with its own renderer?

This is for the GUI build of Emacs, not the terminal (tty) version. Emacs has had a native GUI renderer since the 90s, on macOS it uses Cocoa/NS, on Linux it uses GTK or raw X11. This project replaces that CPU-based drawing pipeline with a GPU backend: Metal on macOS and OpenGL/EGL on Linux. The tty build is unaffected.
Holy crap does the visitors in realtime thing have to be a live region? Every sentence or two: "visitors in realtime party popper 8 weary cat face."
Cool! Regardless of whether your code gets merged, it shows that xdisp.c can be tamed. Like Roger Bannister who ran the miracle mile, you showed that it can be done. Hopefully more will chip in and slay the Emacs redisplay code beast.
Thank you, this means a lot!
What is a backend for GPU?
A backend is a part of a program which receives commands from the frontend (the user-facing part of the program) and performs some actions based on the input received before sending the result back to the frontend.

A GPU (graphics processing unit) is a piece of hardware which is very good at doing a lot of calculations with a lot of numbers very quickly.

Making a backend for the GPU means programming the backend in such a way that it can run on the GPU, thereby (hopefully) getting the program to run faster and more efficiently.

This is outstanding, if I have time I'll be switching over today.

This is the kind of thing that could drive a truly free fork of emacs forward, it's enough better on realistic desktop displays to rally around and as the parent discovered "Free Software" at this point has very little to do with the freedom to do what I want on my computer in a low friction way: an ideological position on "GPUs" as a category is bizarre even by Late Soviet FSF standards. By all means cite a vendor and a policy, but even NVIDIA is in tree now, it's got the same software freedom as ext4 and I don't hear anyone talking about chains on that.

In the age of machine assist emacs could get a modern fast/cachable build, clean under all the sanitizers, io_uring on Linux, deterministic clang formatting, compat break with zero-use junk from the 80s, WASM compilation for polyglot extension (I like lisp but I understand why some people don't), modern networking, modern chrome, 100% vscode compatible LSP, modern theming that defaults to something that doesn't drive users away. I would love to have a ten line init.el instead of 4k of workarounds.

Maybe this can be the nvim moment.

I love emacs but the nvim people have so many nice things and FSF emacs has a shelf life. If someone out of their own time and resources did a cross platform, mechanically verified, dramatically accelerated at HiDPI patch to basically anything else they'd be greeted like a hero.

Keep up the good work legend.

I think a stronger basis for that is probably the Neomacs project aiming to rewrite the elisp layer and all C code in Rust, incorporating GPU rendering etc along the way, see https://github.com/eval-exec/neomacs
Just to clarify: the NVIDIA driver is not in-tree, and probably never will be.

Intel and AMD are, but require proprietary firmware to work, so the freedom aspect is disputed.

Pardon my shorthand. I meant open source and licensed under both MIT and GPLv2 such that distros build it alongside every other `.ko`.

One imagines if anyone has an issue it's with the RISC-V blob in GSP. Now while I myself wouldn't brave the wrath of NVIDIA's lawyers by like, calling Ghidra on it or anything, one imagines it doesn't have a lot of secrets from the motivated tinkerer!

I agree. Nvim already takes notes out of emacs with major contributors using Funnel to use Lisp as a workaround for working with Lua. This would be a step in the right direction for the continued pioneer emacs proves to be.
> In the age of machine assist emacs could get a modern fast/cachable build, clean under all the sanitizers, io_uring on Linux, deterministic clang formatting, compat break with zero-use junk from the 80s, WASM compilation for polyglot extension (I like lisp but I understand why some people don't), modern networking, modern chrome, 100% vscode compatible LSP, modern theming that defaults to something that doesn't drive users away. I would love to have a ten line init.el instead of 4k of workarounds.

A lot of wishes, but no concrete solutions (unlike TFA). A good design doc with factual arguments would be better.

In fairness I only saw this like, an hour ago, so it'll probably be at least until after work before I start messing around with it.
>an ideological position on "GPUs" as a category is bizarre even by Late Soviet FSF standards.

The FSF and the GNU project are both paralyzed by their inability to move on from Stallman. He may have been a visionary 40 years ago but now he's an obsolete dinosaur who hasn't written a line of code in decades and has absolutely no idea how modern computers work.

He can't update his own website. He evidently doesn't seem to know how GPUs work. He does his computing in a very unorthodox and anachronistic manner, and that's great for him, but irrelevant to most people who would benefit from more free software.

Please do not spread lies.

"obsolete dinosaur who hasn't written a line of code in decades"

The most recent code change in Emacs by RMS was on 2026-04-22 (0fb9d096e38), so ~3 months ago. He can write complex code (without AI), such as the `cond*` macro (707 LOC, all macro code), authored and pushed to Emacs on 2024-08-02 (18491f48d97).

I stand corrected on the "writing lines of code in decades" portion but not on the rest.

I think RMS does far more harm to the movement than he does good, and this ignorant, luddite take on GPUs is a poignant example.

Thank you! A small correction on framing though: the goal is not a fork but a patch upstream. The backend is structured precisely to minimize the diff against Emacs mainline. The "nvim moment" comparison is flattering but I would rather this be the patch that makes the FSF argument easier to win than the one that splits the community. That said, your list of modernization items is a fair read of the backlog.
This was almost a good read (a very good goal and a sensible approach), But the pacing of the article smells of LLM. I would suggest to do another pass at editing it out as it diminishes the story.
If you've reached that conclusion, I'm truly proud of my writing technique. I'm sorry to say, though, that your instincts are failing you this time. I write my articles by hand over several days, although it's true that I do consult AI to improve my style, expressions, find synonyms, create tables, and correct spelling mistakes. Thank you for your comment!
I think you'd get your point across better if you avoid consulting AI to improve your style, may lead to less distracting threads like this.
With how straight forward you were about disclosing 100% LLM generated code, I have no reason to doubt you. Besides, the most riveting parts were the quotes from the ensuing discussion even from Stallman himself.
I don’t think it failed. I was reading it and it did not seem written by a LLM (which I was happy for). But a few sentences did have LLM style and they disrupted my reading flow.

This is my heuristics: Usually when writing a story, authors adopt a fluid flow as they know they have your attention. Same as when telling a story. But LLM tooling usually adopt a highly emphatic tone similar to speeches: Short propositions, emotional crescendo, lots of contrast.

The difference in style is like abruptly going from a conversation to having your interlocutors doing a marketing speech in front of a crowd of one. It’s really jarring.

It’s not the whole piece. Just a few places here and there. If you’ve adjusted a few sentences, maybe try leaving them as is after fixing spelling mistakes.

FWIW no one can tell anymore. Claude stopped doing all the LLM ticks like 6 months ago. There's a whole industry of people trying to detect LLM writing and they're getting stomped, this can be and is extremely well studied in the literature.

The criticism is that you did something wildly ambitious and pulled it off. The blog is just well written.

> Claude stopped doing all the LLM ticks like 6 months ago.

Oh God, if only. You’re right that it moved on from the classics, but it has new ones, and they’re just as identifiable.

People clearly can, though, because they did.
I'm inclined to believe the author, given that they were honest about the machine assist on the engineering? Why would they lie about the post and not the artifact?

More broadly, I'm just getting tired of the low effort snark on this. If someone is going to cite a passage, or examples of a theme, do some serious analysis by all means. I'm not trying to tone police high effort comments.

But this drive by "that's LLM output" thing is the new low effort "javascript is just as hard as c++" a.k.a "i don't know how to do that and i have no intention of learning and it feels bad so i'm going to lash out".

Make a case that something is deficient on its merits or don't, but baseless accusations of dishonesty are not a reasonable default. The parent here did real work that no one paid them to do, donated it to the community asking nothing in return, it's meticulous and high value, and they've already been run over by the FSF goons, you really want to pile on with no evidence?

I'm inclined to believe them too, so when he said he used LLMs to tweak the wording, I'll accept that was the case.

Perhaps the opening post was ill-phrased, but I think the second post clarifies it a bit: https://news.ycombinator.com/item?id=48677597 - and I was certainly getting some vague LLM vibes from the writing, so I was curious about this too.

So, whatever it is in the LLM output that is detectable, it's clearly detectable, even with the latest LLMs, and even when it's present possibly only in trace quantities.

Very much this. I really dislike the somewhat corporate and characterless sounding tone of AI.

I really liked the part where he tried to get it into upstream emacs, most of these type of projects never even get there. But yeah things like "bring honest numbers" sounds just weird.

Please, have some mercy, English is not my first language! Thanks for the advice, I'll keep it in mind.
People are paranoid that everything they read was written by a LLM. It's likely that they are even more suspicious because you used one to code.

You should be proud of both the work you did and the article :-).

dont listen to insane people obsessed with llm hatred. thanks for the article
hey, honestly I personally wouldnt mind "unusual" english or some weird sentences. Obviously using AI to proofread and give suggestions is great use of it and I dont see a problem in that. Not a native speaker either so I can definitely relate :) I hope I didnt come off as too harsh, its just due to me seeing a lot of half-baked blog spam on r/emacs Ive gotten a bit sensitive when noticing AI writing.
I honestly just don't get it. I feel people just whine for the sake of complaining about it, to get a feeling of some kind of moral superiority, or something. It's as if they're reading some GRR Martin kind of novel and the dragon slaying portrayal isn't up to their liking. It's not a fucking prose, learn how to extract useful information from a text, you're goddamn programmers, you've been mentally deciphering literal code, probably for a long fucking time, just fucking scan the text with your eyes and comprehend the meaning with your brain. If you don't like the style, just ask the LLM to summarize it for you, dang it. It's like if someone said: "your text appears to be typed in Emacs, sorry, but I won't read it. Try using a less controversial editor next time. Good effort though." Oh fuck you! Don't read it, who cares? Why come complaining about it? I feel like smacking them on the forehead, saying: "good job, you got me, I used AI, now what? Call the police, shoot me, cancel me, send complaints, clog my toilet..." Enormously annoying. More annoying that actually reading text written with AI assistance.
Ignore the detractors, I, for one, enjoyed reading it
cudos
A new CUDA API? For DOS?
No, CUDOS is using CUDA as your OS.

What that has to do with this article about a new device driver for the EMACS OS, I don't quite know...

Why?
What's the article talking about?