Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experimental feature: Black crush mitigation #525

Draft
wants to merge 28 commits into
base: master
Choose a base branch
from

Conversation

utopiafallen
Copy link
Contributor

Experimental feature: Black crush mitigation

The OLED display on my Lenovo Chomebook Duet 5 suffers from black crush so this experimental feature adds a custom gamma curve to boost dark values and alleviate the worst of the black crush.

Since this is forked from my master branch, there's a bunch of identical changes as my other pull request. I'm not even sure this "feature" is desirable so I'm leaving the PR in draft mode.

@moonlight-stream

bob and others added 28 commits October 20, 2022 06:52
Pepper SDK and NaCl in general is EOL for Chrome, although still supported for Chrome Apps.
This means that the Pepper Gamepad API was never updated with rumble support so in order
to add rumble support, rumble messages from Gamestream have to be forwarded to JavaScript
and handled with gamepad.vibrationActuator.playEffect().

Side note, Chrome limits the duration of playEffect to 5 seconds and requesting more than
that causes the vibration request to be rejected.
Moonlight's fullscreen requests generally conflict with
what ChromeOS is trying to do automatically for the app, especially when
using tablet mode. Just remove it for now and let the OS handle
fullscreen.
Otherwise, Esc breaks out of fullscreen instead of being sent to the streaming app.
Adding fullscreen class to the #listener seems to fix the game stream
getting stuck in a black screen. I suspect that #main-content isn't
recomputing its layout when #listener is resized.
Shader is compiling successfully, but the required data not yet hooked up.
A lot of plumbing is set up but Chrome seems sensitive to certain OGL calls
hanging the NaCl module. I don't understand what's happening but this is
version at least draws the video stream again, even if it's messed up.
Finally back to a no-op equivalent state.
XYZ space doesn't automatically adjust chromaticity when luminance changes
meaning colors can shift when Y is changed.
Rumble events may be received for controllers that are no longer present or attached
so they should be dropped instead of being forwarded to JS for handling.
- Black crush now runs in gamma space and does far less work to achieve roughly the same
thing. Unfortunately, there is visual corruption still to be figured out.
- Fixed UI button not reflecting the mitigation state.
Video compression can introduce false colors since all compressors are lossy, and when that
happens, the false colors can be emphasized by the black crush mitigation. To fix this,
the shader explicitly neutralizes pixels below a threshold (currently 4/255) before
applying any compensation curves.
Turns out, the supplied texture can contain negative RGB values. I'm assuming that
compression artifacts are causing the invalid channel values so now I make sure to clamp
input RGB to [0,1] range before computing lookup coordinates for the gamma ramp.

Also simplified the gamma index to be based on max RGB value instead of luminance. Just
seeing if this produces more visually pleasing results.
- Move gamepad index check to the JS side to simplify the code
- Handle gamepads that don't support haptics
Getting weird artifacting with black crush enabled on high contrast areas,
probably need to tune the curve behavior to better hide compression artifacts.
For now, the shader fully skips the curve look up if the mitigation is disabled.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants