593 Commits

Author SHA1 Message Date
Qwerasd
016a26cf98 cleanup: rename text-blending to alpha-blending
+ correct docs
2025-01-27 19:37:44 -05:00
Qwerasd
5c8f984ea1 renderer/Metal: improve linear blending correction
More mathematically sound approach, does a much better job of matching
the appearance of non-linear blending. Removed `experimental` from name
because it's not really an experiment anymore.
2025-01-27 19:15:18 -05:00
Qwerasd
ac568900a5 fix(renderer/Metal): properly load cursor color 2025-01-26 20:40:19 -05:00
Qwerasd
78790f6ef7 fix(Metal): always render explicit background colors fully opaque
This fixes a regression introduced by the rework of this area before
during the color space changes. It seems like the original intent of
this code was the behavior it regressed to, but it turns out to be
better like this.
2025-01-23 20:06:53 -05:00
Julia
9c8c53bffb use main buffer and copy data to fbo texture (opengl) (#5294)
NEEDS REVIEW

continuation of #5037
resolves #4729 

renders all shaders to the default buffer and then copies it to the
designated custom shader texture.

this is a draft pr because:
- it introduces a new shader "pipeline" which doesnt fit in with how the
system was designed to work (which is only rendering to the fbo)
- im not sure if this is the best way to achieve shaders being able to
sample their output while also drawing to the screen. the cusom fbo
(previous implementation) was useful in that it modularized the custom
shader stage in rendering

---------

Co-authored-by: Mitchell Hashimoto <m@mitchellh.com>
2025-01-23 20:57:14 +00:00
Qwerasd
3b8ab10776 fix(renderer): clip terminal contents to expected grid size (#4523)
This significantly improves the robustness of the renderers since it
prevents synchronization issues from causing memory corruption due to
out of bounds read/writes while building the cells.

TODO: when viewport is narrower than renderer grid size, fill blank
margin with bg color- currently appears as black, this only affects
DECCOLM right now, and possibly could create single-frame artefacts
during poorly managed resizes, but it's not ideal regardless.
2025-01-20 18:56:13 -05:00
Mitchell Hashimoto
977c9999dd render consecutive shaders to the fbo (opengl) (#5037)
fixes #4729

allows the shaders to sample each other via the fbo texture.

also, a better example would use the full screen e.g.:
"behind.glsl"
```glsl
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    fragColor = vec4(fragCoord/iResolution.xy, 0.0, 1.0);
}
```

"infront.glsl"
```glsl
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    fragColor = texture(iChannel0, fragCoord/iResolution.xy);
}
```
`ghostty --custom-shader=behind.glsl --custom-shader=infront.glsl`
|before|after|
|-|-|
|
![image](https://github.com/user-attachments/assets/d96cc8f1-7d87-4346-963a-a1fb27b81cba)
|
![image](https://github.com/user-attachments/assets/203c3827-9574-4739-9d54-430dc4a47dcc)|
2025-01-20 10:49:33 -08:00
julia
4cc1fa2111 render consecutive shaders to the fbo
not that big. see comments
2025-01-20 10:36:02 -08:00
Qwerasd
2a1b51ec94 fix(Metal): fix incorrect premultiplication of colors
Also make sure to divide alpha out before applying gamma encoding back
to text color when not using linear blending.
2025-01-16 22:28:22 -05:00
Qwerasd
b1becb12c0 fix(Metal): handle non-extended padding color transparency
We were returning bg colors when we shouldn't have since when we have
background color transparency we need to return any bg color cells as
fully transparent rather than their actual color.
2025-01-15 18:08:11 -05:00
Qwerasd
34abe2ceba fix(macos): prevent transparency leakage/flash in new/resized surfaces
By using the `CAMetalLayer`'s `backgroundColor` property instead of
drawing the background color in our shader, it is always stretched to
cover the full surface, even when live-resizing, and it doesn't require
us to draw a frame for it to be initialized so there's no transparent
flash when a new surface is created (as in a new split/tab).

This commit also allows for hot reload of `background-opacity`,
`window-vsync`, and `window-colorspace`.
2025-01-14 20:23:21 -05:00
Mitchell Hashimoto
a8b9c5bea5 config: remove experimental linear and merge into text-blending 2025-01-13 13:59:37 -08:00
Qwerasd
fca336c32d Metal: blend in Display P3 color space, add option for linear blending
This commit is quite large because it's fairly interconnected and can't
be split up in a logical way. The main part of this commit is that alpha
blending is now always done in the Display P3 color space, and depending
on the configured `window-colorspace` colors will be converted from sRGB
or assumed to already be Display P3 colors. In addition, a config option
`text-blending` has been added which allows the user to configure linear
blending (AKA "gamma correction"). Linear alpha blending also applies to
images and makes custom shaders receive linear colors rather than sRGB.

In addition, an experimental option has been added which corrects linear
blending's tendency to make dark text look too thin and bright text look
too thick. Essentially it's a correction curve on the alpha channel that
depends on the luminance of the glyph being drawn.
2025-01-13 13:50:29 -08:00
Mitchell Hashimoto
300884d50f refactor(font): move Metrics from Face to Collection (#4739)
This refactor enables two very significant improvements to our font
handling, which I will be implementing next:
1. Automatically adjust size of fallback faces to better align with the
primary face, a la CSS
[`font-size-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size-adjust).
[^1]
2. Move glyph resizing/positioning out of GPU-land and in to
`renderGlyph` and apply alignment/resizing rules from the nerd fonts
patcher[^2] to the glyphs at rasterization time, so that we can ensure
exact cell fits and swap out our embedded JB Mono with an unpatched
version with a separate dedicated symbols-only nerd font.

In addition to being necessary prep work for those two changes, this PR
is also a minor but real stand-alone improvement. By only computing the
cell metrics for our primary font, we avoid a *lot* of wasted work when
loading fallback fonts, and also avoid that being a source of load
errors, which we don't yet handle gracefully[^3].

To validate this PR I've run the full set of font backend tests locally
on my Mac with no failures, and did a sanity check of running Ghostty
with both renderers and with CoreText and FreeType font backends and
then `cat`ing a file that requires fallback fonts to render, and
everything looks correct.

[^1]: #3029

[^2]: The alignment and resizing rules for the nerd font symbols are
defined in the patcher
[here](6d0b8ba05a/font-patcher (L866-L1151))

[^3]: #2991
2025-01-07 20:43:48 -08:00
Gregory Anders
b2716375ac renderer: respect reverse with cursor-invert-fg-bg 2025-01-07 12:01:45 -06:00
Qwerasd
540fcc0b69 refactor(font): move Metrics out of face
in preparation to move ownership of metrics from faces to collections
2025-01-06 20:13:45 -05:00
yonihemi
63a47d0ba5 iOS: Fix crash on device 2025-01-06 22:01:41 +08:00
Mitchell Hashimoto
62dd468500 font(coretext): add config to adjust strength of font-thicken. (#4531)
This is achieved by rendering to an alpha-only context rather than a
normal single-channel context, and adjusting the brightness at which
CoreText thinks it's drawing the glyph, which affects how it applies
font smoothing (which is what `font-thicken` enables).
2025-01-05 12:53:14 -08:00
Qwerasd
25a112469c font(coretext): add config to adjust strength of font-thicken.
This is achieved by rendering to an alpha-only context rather than a
normal single-channel context, and adjusting the brightness at which
coretext thinks it's drawing the glyph, which affects how it applies
font smoothing (which is what `font-thicken` enables).
2025-01-03 14:19:19 -05:00
Peter Cock
6459e5c8ca Fixing a few typos in the source code comments (#4529) 2025-01-03 11:00:45 -08:00
Bryan Lee
ac524b6c34 Correct typos and update typos.toml 2025-01-03 09:55:21 +08:00
Mitchell Hashimoto
64ea3a1a29 renderer: track if fg/bg/cursor color is explicitly set by an OSC (#3228)
The renderer must track if the foreground, background, and cursor colors
are explicitly set by an OSC so that changes are not overridden when the
config file is reloaded.

Fixes: https://github.com/ghostty-org/ghostty/issues/2795
2024-12-29 09:05:37 -08:00
XiaoYan Li
28bbd526f2 Fix the typing error when building on Linux
Co-authored-by: Gareth Widlansky <101901964+gerblesh@users.noreply.github.com>
2024-12-28 19:37:24 -08:00
Xiaoyan Li
2993d12de7 Use premultiplied alpha for renderer clearColor
Fixes #3324
2024-12-28 19:37:24 -08:00
Gregory Anders
eef9664ef8 renderer: track if fg/bg/cursor color is explicitly set by an OSC
The renderer must track if the foreground, background, and cursor colors
are explicitly set by an OSC so that changes are not overridden when the
config file is reloaded.
2024-12-26 20:18:45 -06:00
Mitchell Hashimoto
bd90a6dd3b kittygfx: placement with rows (r) param scrolls properly out of viewport
Fixes #2332

Two bugs fixed to fix this behavior:

1. Our destination height didn't account for the top-left being
   offscreen.

2. We were using the wrong height for the source rectangle. When a rows
   param (r=) is specified, the image height and destination height are
   at different scales. We were using the viewport scale for the offset
   but it should be the image scale.
2024-12-23 14:11:14 -08:00
Mitchell Hashimoto
a908aca563 kittygfx: z-index handling fixes
Fixes #2921

Our z-index handling was pretty much completely broken, hence I can't
think of a better initial commit message. We were splitting the
placements at the wrong points and just generally putting images in the
wrong z-index. I'm shocked this didn't come up earlier.
2024-12-23 12:46:46 -08:00
Qwerasd
4ca6413ec9 renderer: do not constrain color glyphs
There is no reason to and I do not know where this assumption came from.
It's very possible for a colored glyph to (intentionally!) exceed the
cell bounds, and we shouldn't be stopping this...
2024-12-19 11:21:57 -05:00
Mitchell Hashimoto
a482224da8 renderer: set QoS class of the renderer thread on macOS
This sets the macOS QoS class of the renderer thread. Apple
recommends[1] that all threads should have a QoS class set, and there
are many benefits[2] to that, mainly around power management moreso than
performance I'd expect.

In this commit, I start by setting the QoS class of the renderer thread.
By default, the renderer thread is set to user interactive, because it
is a UI thread after all. But under some conditions we downgrade:

  - If the surface is not visible at all (i.e. another window is fully
    covering it or its minimized), we set the QoS class to utility. This
    is lower than the default, previous QoS and should help macOS
    unschedule the workload or move it to a different core.

  - If the surface is visible but not focused, we set the QoS class to
    user initiated. This is lower than user interactive but higher than
    default. The renderer should remain responsive but not consume as
    much time as it would if it was user interactive.

I'm unable to see any noticable difference in anything from these
changes. Unfortunately it doesn't seem like Apple provides good tools to
play around with this.

We should continue to apply QoS classes to our other threads on macOS.

[1]: https://developer.apple.com/documentation/apple-silicon/tuning-your-code-s-performance-for-apple-silicon?preferredLanguage=occl
[2]: https://blog.xoria.org/macos-tips-threading/
2024-11-26 15:43:35 -08:00
Mitchell Hashimoto
3392659e1f Revert "macos: enable Metal shader logging"
This reverts commit aad101565abff3368af76e8c2e93cbe7c278a89f.
2024-11-20 15:01:27 -08:00
Mitchell Hashimoto
53dba182bf Merge pull request #2735 from ghostty-org/theme
Configuration to specify separate light/dark mode theme
2024-11-20 14:12:36 -08:00
Mitchell Hashimoto
f8a8b0464c renderer/opengl: fix memory leak when copying font features 2024-11-20 14:08:00 -08:00
Mitchell Hashimoto
aad101565a macos: enable Metal shader logging
This enables the compile options and Xcode configuration so that logging
in Metal shaders shows up in our Xcode debug console. This doesn't add
any log messages, but makes it so that when we iterate on the shaders in
the future, we can add and see logs to help us out.
2024-11-19 18:59:41 -08:00
Mitchell Hashimoto
7605472922 Balance padding uses the explicit padding value for grid calculations
This fixes window resize not working properly when
`window-padding-balance` is set to true.
2024-11-15 15:16:00 -08:00
Mitchell Hashimoto
1792ddfff1 remove some unused structs 2024-11-14 14:25:42 -08:00
Mitchell Hashimoto
72a3d22e69 apprt/gtk: use new size structs 2024-11-14 14:04:20 -08:00
Mitchell Hashimoto
3b856f6269 renderer/opengl: update to new size struct 2024-11-14 13:49:49 -08:00
Mitchell Hashimoto
b3b5e15e96 renderer/metal: use new size struct 2024-11-14 13:44:05 -08:00
Mitchell Hashimoto
6f62944b9c renderer: message uses new size struct 2024-11-14 13:34:36 -08:00
Mitchell Hashimoto
dcb1ce8377 termio: change resize message to use new size struct 2024-11-14 13:23:24 -08:00
Mitchell Hashimoto
ca8130bec9 core: make surface use only renderer.Size 2024-11-14 13:15:56 -08:00
Mitchell Hashimoto
c1c9aac0fe renderer: dedicated size struct, defined coordinate spaces 2024-11-14 12:36:21 -08:00
Mitchell Hashimoto
a436bd0af6 move datastructures to dedicated "datastruct" package 2024-11-07 14:39:10 -08:00
Mitchell Hashimoto
aed51fd0b0 terminal: PageList rename "page" to "node" everywhere
This is more correct: a pagelist is a linked list of nodes, not pages.
The nodes themselves contain pages but we were previously calling the
nodes "pages" which was confusing, especially as I plan some future
changes to the way pages are stored.
2024-11-07 13:44:39 -08:00
Emily
20a77123d4 renderer/metal: prefer low‐power GPUs
Some Intel MacBook Pro laptops have both an integrated and discrete
GPU and support automatically switching between them. The system
uses the integrated GPU by default, but the default Metal device on
those systems is the discrete GPU. This means that Metal‐using
applications activate it by default, presumably as the intended
audience is high‐performance graphics applications.

This is unfortunate for productivity applications like terminals,
however, as the discrete GPU decreases battery life and worsens the
thermal throttling problems these machines have always had. Prefer
to use an integrated GPU when present and not using an external GPU.

The behaviour should be unchanged on Apple Silicon, as the platform
only supports one GPU. I have confirmed that the resulting app runs,
works, and doesn’t activate the AMD GPU on my MacBook Pro, but have
not done any measurements of the resulting performance impact. If
it is considered sufficiently noticeable, a GPU preference setting
could be added.

See <https://github.com/zed-industries/zed/issues/5124>,
<https://github.com/zed-industries/zed/pull/13685>,
<https://github.com/zed-industries/zed/pull/14738>, and
<https://github.com/zed-industries/zed/pull/14744> for discussion,
measurements, and changes relating to this issue in the Zed
project. The logic implemented here reflects what Zed ended up
settling on.

The [Metal documentation] recommends using
`MTLCopyAllDevicesWithObserver` to receive notifications of when
the list of available GPUs changes, such as when [external GPUs
are connected or disconnected]. I didn’t bother implementing that
because it seemed like a lot of fussy work to deal with migrating
everything to a new GPU on the fly just for a niche use case on a
legacy platform. Zed doesn’t implement it and I haven’t heard
about anyone complaining that their computer caught fire when they
unplugged an external GPU, so hopefully it’s fine.

[Metal documentation]: https://developer.apple.com/documentation/metal/gpu_devices_and_work_submission/multi-gpu_systems/finding_multiple_gpus_on_an_intel-based_mac
[external GPUs are connected or disconnected]: https://developer.apple.com/documentation/metal/gpu_devices_and_work_submission/multi-gpu_systems/handling_external_gpu_additions_and_removals

Closes: #2572
2024-11-04 00:35:21 +00:00
Emily
9c8b00f87d renderer/metal: release device on deinit() 2024-11-04 00:21:39 +00:00
Emily
e5f9f222b2 renderer/metal: use release() consistently
I’m not sure why this variation was here previously – maybe it
predated the introduction of `release()`?
2024-11-04 00:21:39 +00:00
Marijn Besseling
4496e7d314 implement overline decoration (SGR 53/55) 2024-10-21 08:36:08 -04:00
Mitchell Hashimoto
ccb97c6c33 Merge pull request #2417 from qwerasd205/misc-shaper-fixes
Renderer `rebuildCells` rework
2024-10-12 09:39:08 -07:00
Yi Ming
0571c50d63 renderer: generalize the definition of "space" 2024-10-12 17:56:51 +08:00