Scale brightness transition steps to the backlight's range - #172
Open
TheDiscordian wants to merge 3 commits into
Open
Scale brightness transition steps to the backlight's range#172TheDiscordian wants to merge 3 commits into
TheDiscordian wants to merge 3 commits into
Conversation
On sysfs backlights with a large max_brightness (e.g. amdgpu with 62194 levels), absolute transition steps of a few units combined with the 1 ms step interval turn every prediction change into a continuous stream of sysfs writes (hundreds per second). Each write emits a kernel uevent that systemd rebroadcasts on the system bus as PropertiesChanged signals for the device unit; busy D-Bus peers subscribed to broadcasts can overflow their queues and get disconnected by dbus-broker. Introduce a per-device minimum step (max_brightness / 256, floor 1) used both as a deadband for new predictions and as the minimum transition step, and clamp transition writes to the target so the last step lands exactly on it. Devices with max_brightness <= 256 keep the previous behaviour exactly (min_step = 1). Measured on a Framework 16 (amdgpu, max_brightness 62194): ~540 backlight uevents/s before, ~2.5/s after, with auto-adjustment still working. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
|
So sorry, my Claude opened this entirely without me knowing. I haven't reviewed this, feel free to close. if this PR is unwelcome For context my games were crashing and I couldn't figure out why. After months fable suddenly figured out the culprit: wluma. This patch does seem to fix the crash (and it seems to be a reasonable change, but again, haven't really reviewed it myself). Edit: While this does fix the crash. Playing a game like Satisfactory it makes the brightness adjustments a bit jarring and jumpy, but normal use it seems fine. I'm making a service to simply not run wluma while mangohud is running (hacky way to check if I'm running a game). |
Enlarging the step while keeping the 1 ms interval made small and medium transitions complete in a few milliseconds, which looks like an instant jump. When min_step binds, stretch the per-step interval so the ramp still spans the transition duration; when it does not bind, step and interval are unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On sysfs backlights with a large
max_brightness, wluma writes to the brightness file essentially continuously. My laptop (Framework 16, amdgpu,max_brightness= 62194) sees ~540 sysfs writes per second in steady state: prediction noise of a few units (±0.003% of the range) starts a new transition, and since any delta ≤ 200 units getsstep = 1with a 1 ms step interval, wluma crawls unit-by-unit toward a target that never stops moving.This is more than log noise. Every write emits a kernel uevent, and systemd rebroadcasts each one on the system D-Bus as
PropertiesChangedfor the device unit and itssystemd-backlight@service (~2,200 signals/s measured withdbus-monitor --system). Busy peers subscribed to broadcasts can't drain their queues and get force-disconnected by dbus-broker:In my case that killed a running Steam game and Steam itself mid-session. Devices with a small brightness range (100–255) never see this because prediction noise rounds to zero units — which is probably why it has gone unnoticed.
Fix
min_step()—max_brightness / 256, floor 1 — toBacklight, exposed viaBrightness.update_target: predictions withinmin_stepof the current value are ignored (generalizes the existingdesired == currentcheck).min_stepbinds, stretch the per-step interval so the ramp still spansTRANSITION_MAX_MS— fewer writes, same transition duration, so transitions stay visually smooth instead of completing in a few milliseconds.desiredinstead of overshooting.Devices with
max_brightness≤ 256 getmin_step= 1, which preserves the previous behaviour exactly — all existing tests pass unchanged. DDC/CI outputs are unaffected (min_step= 1 on their 0–100 range).Results (Framework 16, amdgpu, max 62194)
Auto-adjustment still works. Measured a forced dim/re-brighten cycle: ~70 evenly spaced steps spanning the full transition window per direction.