steamcompmgr: New night mode color toys

This commit is contained in:
Joshua Ashton 2022-02-08 02:44:36 +00:00 committed by Joshie
parent c61d936cd9
commit 02e0086856
4 changed files with 80 additions and 7 deletions

View file

@ -1373,18 +1373,62 @@ bool drm_set_color_gains(struct drm_t *drm, float *gains)
return false; return false;
} }
bool drm_set_color_linear_gains(struct drm_t *drm, float *gains)
{
for (int i = 0; i < 3; i++)
drm->pending.color_linear_gain[i] = gains[i];
for (int i = 0; i < 3; i++)
{
if ( drm->current.color_linear_gain[i] != drm->pending.color_linear_gain[i] )
return true;
}
return false;
}
bool drm_set_color_gain_blend(struct drm_t *drm, float blend)
{
drm->pending.gain_blend = blend;
if ( drm->current.gain_blend != drm->pending.gain_blend )
return true;
return false;
}
inline float lerp( float a, float b, float t )
{
return a + t * (b - a);
}
inline uint16_t drm_calc_lut_value( float input, float flLinearGain, float flGain, float flBlend )
{
float flValue = lerp( flGain * input, linear_to_srgb( flLinearGain * srgb_to_linear( input ) ), flBlend );
return (uint16_t)quantize( flValue, (float)UINT16_MAX );
}
bool drm_update_gamma_lut(struct drm_t *drm) bool drm_update_gamma_lut(struct drm_t *drm)
{ {
if (drm->pending.color_gain[0] == drm->current.color_gain[0] && if (drm->pending.color_gain[0] == drm->current.color_gain[0] &&
drm->pending.color_gain[1] == drm->current.color_gain[1] && drm->pending.color_gain[1] == drm->current.color_gain[1] &&
drm->pending.color_gain[2] == drm->current.color_gain[2]) drm->pending.color_gain[2] == drm->current.color_gain[2] &&
drm->pending.color_linear_gain[0] == drm->current.color_linear_gain[0] &&
drm->pending.color_linear_gain[1] == drm->current.color_linear_gain[1] &&
drm->pending.color_linear_gain[2] == drm->current.color_linear_gain[2] &&
drm->pending.gain_blend == drm->current.gain_blend )
{ {
return true; return true;
} }
if (drm->pending.color_gain[0] == 1.0f && bool color_gain_identity = drm->pending.gain_blend == 1.0f ||
drm->pending.color_gain[1] == 1.0f && ( drm->pending.color_gain[0] == 1.0f &&
drm->pending.color_gain[2] == 1.0f) drm->pending.color_gain[1] == 1.0f &&
drm->pending.color_gain[2] == 1.0f );
bool linear_gain_identity = drm->pending.gain_blend == 0.0f ||
( drm->pending.color_linear_gain[0] == 1.0f &&
drm->pending.color_linear_gain[1] == 1.0f &&
drm->pending.color_linear_gain[2] == 1.0f );
if ( color_gain_identity && linear_gain_identity )
{ {
drm->pending.gamma_lut_id = 0; drm->pending.gamma_lut_id = 0;
return true; return true;
@ -1395,9 +1439,9 @@ bool drm_update_gamma_lut(struct drm_t *drm)
for ( int i = 0; i < lut_entries; i++ ) for ( int i = 0; i < lut_entries; i++ )
{ {
float input = float(i) / float(lut_entries - 1); float input = float(i) / float(lut_entries - 1);
gamma_lut[i].red = quantize( linear_to_srgb( drm->pending.color_gain[0] * srgb_to_linear( input ) ), (float)UINT16_MAX ); gamma_lut[i].red = drm_calc_lut_value( input, drm->pending.color_linear_gain[0], drm->pending.color_gain[0], drm->pending.gain_blend );
gamma_lut[i].green = quantize( linear_to_srgb( drm->pending.color_gain[1] * srgb_to_linear( input ) ), (float)UINT16_MAX ); gamma_lut[i].green = drm_calc_lut_value( input, drm->pending.color_linear_gain[1], drm->pending.color_gain[1], drm->pending.gain_blend );
gamma_lut[i].blue = quantize( linear_to_srgb( drm->pending.color_gain[2] * srgb_to_linear( input ) ), (float)UINT16_MAX ); gamma_lut[i].blue = drm_calc_lut_value( input, drm->pending.color_linear_gain[2], drm->pending.color_gain[2], drm->pending.gain_blend );
} }
uint32_t blob_id = 0; uint32_t blob_id = 0;

View file

@ -97,6 +97,8 @@ struct drm_t {
uint32_t mode_id; uint32_t mode_id;
uint32_t gamma_lut_id; uint32_t gamma_lut_id;
float color_gain[3] = { 1.0f, 1.0f, 1.0f }; float color_gain[3] = { 1.0f, 1.0f, 1.0f };
float color_linear_gain[3] = { 1.0f, 1.0f, 1.0f };
float gain_blend = 0.0f;
} current, pending; } current, pending;
/* FBs in the atomic request, but not yet submitted to KMS */ /* FBs in the atomic request, but not yet submitted to KMS */
@ -154,7 +156,9 @@ bool drm_set_connector( struct drm_t *drm, struct connector *conn );
bool drm_set_mode( struct drm_t *drm, const drmModeModeInfo *mode ); bool drm_set_mode( struct drm_t *drm, const drmModeModeInfo *mode );
bool drm_set_refresh( struct drm_t *drm, int refresh ); bool drm_set_refresh( struct drm_t *drm, int refresh );
bool drm_set_resolution( struct drm_t *drm, int width, int height ); bool drm_set_resolution( struct drm_t *drm, int width, int height );
bool drm_set_color_linear_gains(struct drm_t *drm, float *gains);
bool drm_set_color_gains(struct drm_t *drm, float *gains); bool drm_set_color_gains(struct drm_t *drm, float *gains);
bool drm_set_color_gain_blend(struct drm_t *drm, float blend);
bool drm_update_gamma_lut(struct drm_t *drm); bool drm_update_gamma_lut(struct drm_t *drm);
char *find_drm_node_by_devid(dev_t devid); char *find_drm_node_by_devid(dev_t devid);

View file

@ -3608,9 +3608,30 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
gains[i] = bit_cast<float>( user_gains[i] ); gains[i] = bit_cast<float>( user_gains[i] );
} }
if ( drm_set_color_linear_gains( &g_DRM, gains ) )
hasRepaint = true;
}
if ( ev->atom == ctx->atoms.gamescopeColorGain )
{
std::vector< uint32_t > user_gains;
bool bHasColor = get_prop( ctx, ctx->root, ctx->atoms.gamescopeColorGain, user_gains );
float gains[3] = { 1.0f, 1.0f, 1.0f };
if ( bHasColor && user_gains.size() == 3 )
{
for (int i = 0; i < 3; i++)
gains[i] = bit_cast<float>( user_gains[i] );
}
if ( drm_set_color_gains( &g_DRM, gains ) ) if ( drm_set_color_gains( &g_DRM, gains ) )
hasRepaint = true; hasRepaint = true;
} }
if ( ev->atom == ctx->atoms.gamescopeColorLinearGainBlend )
{
float flBlend = bit_cast<float>(get_prop(ctx, ctx->root, ctx->atoms.gamescopeColorLinearGainBlend, 0));
if ( drm_set_color_gain_blend( &g_DRM, flBlend ) )
hasRepaint = true;
}
if ( ev->atom == ctx->atoms.gamescopeXWaylandModeControl ) if ( ev->atom == ctx->atoms.gamescopeXWaylandModeControl )
{ {
std::vector< uint32_t > xwayland_mode_ctl; std::vector< uint32_t > xwayland_mode_ctl;
@ -4494,6 +4515,8 @@ void init_xwayland_ctx(gamescope_xwayland_server_t *xwayland_server)
ctx->atoms.gamescopeFSRSharpness = XInternAtom( ctx->dpy, "GAMESCOPE_FSR_SHARPNESS", false ); ctx->atoms.gamescopeFSRSharpness = XInternAtom( ctx->dpy, "GAMESCOPE_FSR_SHARPNESS", false );
ctx->atoms.gamescopeColorLinearGain = XInternAtom( ctx->dpy, "GAMESCOPE_COLOR_LINEARGAIN", false ); ctx->atoms.gamescopeColorLinearGain = XInternAtom( ctx->dpy, "GAMESCOPE_COLOR_LINEARGAIN", false );
ctx->atoms.gamescopeColorGain = XInternAtom( ctx->dpy, "GAMESCOPE_COLOR_GAIN", false );
ctx->atoms.gamescopeColorLinearGainBlend = XInternAtom( ctx->dpy, "GAMESCOPE_COLOR_LINEARGAIN_BLEND", false );
ctx->atoms.gamescopeXWaylandModeControl = XInternAtom( ctx->dpy, "GAMESCOPE_XWAYLAND_MODE_CONTROL", false ); ctx->atoms.gamescopeXWaylandModeControl = XInternAtom( ctx->dpy, "GAMESCOPE_XWAYLAND_MODE_CONTROL", false );
ctx->root_width = DisplayWidth(ctx->dpy, ctx->scr); ctx->root_width = DisplayWidth(ctx->dpy, ctx->scr);

View file

@ -117,6 +117,8 @@ struct xwayland_ctx_t
Atom gamescopeFSRSharpness; Atom gamescopeFSRSharpness;
Atom gamescopeColorLinearGain; Atom gamescopeColorLinearGain;
Atom gamescopeColorGain;
Atom gamescopeColorLinearGainBlend;
Atom gamescopeXWaylandModeControl; Atom gamescopeXWaylandModeControl;
} atoms; } atoms;