The hardware cursor plane is blended by the display engine after the
compositor has already encoded its framebuffer into the output's colour
space. renderHWCursorBuffer() renders the cursor as plain sRGB, so on a
colour-managed output those values are reinterpreted in the output space.
On a PQ output that means a white cursor lands near peak luminance and is
blinding relative to every other SDR surface, which is what
hyprwm/Hyprland#14419 reports. Setting cursor:no_hardware_cursors=1 avoids
it because software cursors go through the normal, colour-managed pass.
Tag the cursor framebuffer with the monitor's image description so the
texture pass converts into the output colour space. The target selection in
CHyprOpenGLImpl already prefers the current FB's image description when it
has one, so no other plumbing is needed.
wlroots fixed the same issue in its DRM backend (!5190, "cursor: apply
output image description when preparing texture").
applyCMType() replaces the output's image description and marks the blur FB
dirty, but never damages the monitor. Anything already composited under the
previous colour transform therefore stays on screen until something else
happens to damage it.
It is most visible on transparent surfaces after leaving HDR: a faint grey
overlay that persists for roughly half a second, until the surface repaints
for an unrelated reason. Confirmed by A/B - leaving HDR normally shows it,
while leaving HDR followed immediately by a forced full repaint does not.
This was previously masked by the ~1s blank an HDR transition used to cause,
which force-repainted everything.
* add systemd session target
* session: stop graphical-session so we block, near other systemd cleanup
* session: don't start session ourselves if MANAGERPID is set
This avoids doing systemd stuff if we're already in a systemd-managed
session, like UWSM. Env vars and targets and such should already be
handled for us.
* session: store state, rather than rechecking env var at exit
---------
Co-authored-by: Dregu <dregu@dreg.us>
* input/layers: let new layer-surfaces take pointer focus
* input/layers: decouple pointer focus from keyboard interactivity
zwlr_layer_surface_v1::set_keyboard_interactivity:
"Layer surfaces receive pointer, touch, and tablet events normally.
If you do not want to receive them, set the input region on your
surface to an empty region."
We were previously treating keyboard interactivity also as pointer
interactivity, by forcing pointer focus onto any new
'keyboard_interactivity != none' surfaces in onMap(), as well as
redirecting all regular pointer input to any existing
'keyboard_interactivity == exclusive' surface.
* layers: rename 'interactivity' identifiers to specify *keyboard*-interactivity
The Lua config field is also renamed from 'interactivity' to
'keyboard_interactivity'.
std::memcmp returns a nonzero value when the buffers differ, so
hdrMetadataEqual() returned true for differing metadata and false for
identical metadata. The caller in commitFrame compares
!hdrMetadataEqual(WANTED, CURRENT), which inverted this again: identical
HDR metadata was treated as changed every frame, re-sending
AQ_OUTPUT_STATE_HDR and forcing a full DRM modeset on every commit.
Fixes a per-frame modeset loop on displays with HDR metadata configured
(e.g. cm=hdredid).
Co-authored-by: neonvoidx <me@neonvoid.dev>
* shaders: make each SRC/DST TF a variant
by making each SRC/DS transferunction a variant we reduce the branching
and instruction count by up to 60%, measured with INTEL_DEBUG=fs,gs,vs
* opengl: cache activetex, blendfunc, VBO, FBO
this was about 9% of a 10 second apitrace capture of redundant gl calls
with same things over and over. just cache it like we do with other
things. because i dont trust the driver to even act accordingly.
* hyprctl(repl): go interactive if no Lua was given via args
The previous check would mess up if `-i` was provided, since it'd see
*an argument* and refuse to go interactive, even when it should've (i.e.
`hyprctl -i 0 repl`).
* ipc(socket1): new escape parsing for batch commands
Semicolons are still the command separator, so those have to be escaped
if they appear anywhere inside of commands (e.g. multi-statement Lua
code). Also, literal backslashes need to be escaped as well.
* tests(ipc): add test for hyprctl batch mode
This test case includes slightly weird stuff (semicolons in Lua code;
square brackets) that would break the old parsing logic.
* format: dang braces
Compare the metadata we would send against what is already committed and
send if there is any difference.
Found this testing whether MaxCLL influences in-panel tonemapping.
setHDRMetadata was only called when the monitor entered or left HDR or
in some cases surrounding direct scanout. Changes to the metadata itself
while the monitor stayed in HDR was computed and stored in the image
description, but never sent.
This particularly effects mastering data and min/max/max_avg luminance
changes.
Signed-off-by: Will Temple <will@wtemple.net>
the clear was scissored to m_renderData.damage while we fakeDamaged full
monitor. so in render pass when m_blurFBShouldRender is hit the FB was
cleared over partial damage but rendered over whole monitor causing
stale blur blends into the new outside damage. so save old damage,
render fakeDamage, restore old damage.
invalidate({GL_DEPTH_STENCIL_ATTACHMENT}) at end of
renderTextureWithBlurInternal cant set m_cleared = false because its not
invalidated the COLOR_ATTACHMENT, so guard invalidate.