drm, steamcompmgr: Move color mgmt state out of DRM
Want to use this in composite too
This commit is contained in:
parent
a980d912aa
commit
a5d00f436c
4 changed files with 231 additions and 283 deletions
275
src/drm.cpp
275
src/drm.cpp
|
@ -1060,9 +1060,6 @@ bool init_drm(struct drm_t *drm, int width, int height, int refresh, bool wants_
|
|||
drm->flipcount = 0;
|
||||
drm->needs_modeset = true;
|
||||
|
||||
// Enable color mgmt by default.
|
||||
drm->pending.color_mgmt.enabled = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1277,10 +1274,6 @@ int drm_commit(struct drm_t *drm, const struct FrameInfo_t *frameInfo )
|
|||
{
|
||||
if ( drm->pending.mode_id != drm->current.mode_id )
|
||||
drmModeDestroyPropertyBlob(drm->fd, drm->current.mode_id);
|
||||
if ( drm->pending.gamma_lut_id != drm->current.gamma_lut_id )
|
||||
drmModeDestroyPropertyBlob(drm->fd, drm->current.gamma_lut_id);
|
||||
if ( drm->pending.degamma_lut_id != drm->current.degamma_lut_id )
|
||||
drmModeDestroyPropertyBlob(drm->fd, drm->current.degamma_lut_id);
|
||||
for ( uint32_t i = 0; i < ColorHelpers_EOTFCount; i++ )
|
||||
{
|
||||
if ( drm->pending.lut3d_id[i] != drm->current.lut3d_id[i] )
|
||||
|
@ -1932,24 +1925,7 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
|
|||
drm->pending.screen_type = drm_get_screen_type(drm);
|
||||
|
||||
drm_update_vrr_state(drm);
|
||||
if (!drm->pending.color_mgmt.enabled)
|
||||
{
|
||||
for ( uint32_t i = 0; i < ColorHelpers_EOTFCount; i++ )
|
||||
{
|
||||
drm->pending.lut3d_id[ i ] = 0;
|
||||
drm->pending.shaperlut_id[ i ] = 0;
|
||||
}
|
||||
}
|
||||
else if (drm->pending.color_lut3d_override || drm->pending.color_shaperlut_override)
|
||||
{
|
||||
// LUT overrides
|
||||
drm_update_lut3d_override(drm);
|
||||
drm_update_shaperlut_override(drm);
|
||||
}
|
||||
else
|
||||
{
|
||||
drm_update_color_mgmt(drm);
|
||||
}
|
||||
drm_update_color_mgmt(drm);
|
||||
|
||||
drm->fbids_in_req.clear();
|
||||
|
||||
|
@ -1992,8 +1968,6 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
|
|||
}
|
||||
}
|
||||
|
||||
drm->pending.regamma_tf = DRM_VALVE1_TRANSFER_FUNCTION_DEFAULT;
|
||||
|
||||
uint32_t flags = DRM_MODE_ATOMIC_NONBLOCK;
|
||||
|
||||
// We do internal refcounting with these events
|
||||
|
@ -2124,27 +2098,6 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (drm->crtc->has_gamma_lut)
|
||||
{
|
||||
ret = add_crtc_property(drm->req, drm->crtc, "GAMMA_LUT", drm->pending.gamma_lut_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drm->crtc->has_degamma_lut)
|
||||
{
|
||||
ret = add_crtc_property(drm->req, drm->crtc, "DEGAMMA_LUT", drm->pending.degamma_lut_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drm->crtc->has_ctm)
|
||||
{
|
||||
ret = add_crtc_property(drm->req, drm->crtc, "CTM", drm->pending.ctm_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (drm->crtc->has_vrr_enabled)
|
||||
{
|
||||
ret = add_crtc_property(drm->req, drm->crtc, "VRR_ENABLED", drm->pending.vrr_enabled);
|
||||
|
@ -2182,27 +2135,6 @@ int drm_prepare( struct drm_t *drm, bool async, const struct FrameInfo_t *frameI
|
|||
}
|
||||
|
||||
if (drm->crtc != nullptr) {
|
||||
if ( drm->crtc->has_gamma_lut && drm->pending.gamma_lut_id != drm->current.gamma_lut_id )
|
||||
{
|
||||
int ret = add_crtc_property(drm->req, drm->crtc, "GAMMA_LUT", drm->pending.gamma_lut_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ( drm->crtc->has_degamma_lut && drm->pending.degamma_lut_id != drm->current.degamma_lut_id )
|
||||
{
|
||||
int ret = add_crtc_property(drm->req, drm->crtc, "DEGAMMA_LUT", drm->pending.degamma_lut_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ( drm->crtc->has_ctm && drm->pending.ctm_id != drm->current.ctm_id )
|
||||
{
|
||||
int ret = add_crtc_property(drm->req, drm->crtc, "CTM", drm->pending.ctm_id);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ( drm->crtc->has_vrr_enabled && drm->pending.vrr_enabled != drm->current.vrr_enabled )
|
||||
{
|
||||
int ret = add_crtc_property(drm->req, drm->crtc, "VRR_ENABLED", drm->pending.vrr_enabled );
|
||||
|
@ -2338,92 +2270,6 @@ static void drm_unset_connector( struct drm_t *drm )
|
|||
drm->needs_modeset = true;
|
||||
}
|
||||
|
||||
bool drm_set_3dlut(struct drm_t *drm, const char *path)
|
||||
{
|
||||
bool had_lut = drm->current.color_lut3d_override != nullptr;
|
||||
|
||||
drm->pending.color_lut3d_override = nullptr;
|
||||
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
return had_lut;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
size_t elems = fsize / sizeof(drm_color_lut);
|
||||
|
||||
if (elems == 0) {
|
||||
return had_lut;
|
||||
}
|
||||
|
||||
auto data = std::make_shared<std::vector<drm_color_lut>>(elems);
|
||||
fread(data->data(), elems, sizeof(drm_color_lut), f);
|
||||
|
||||
drm->pending.color_lut3d_override = std::move(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool drm_set_shaperlut(struct drm_t *drm, const char *path)
|
||||
{
|
||||
bool had_lut = drm->current.color_shaperlut_override != nullptr;
|
||||
|
||||
drm->pending.color_shaperlut_override = nullptr;
|
||||
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
return had_lut;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
size_t elems = fsize / sizeof(drm_color_lut);
|
||||
|
||||
if (elems == 0) {
|
||||
return had_lut;
|
||||
}
|
||||
|
||||
auto data = std::make_shared<std::vector<drm_color_lut>>(elems);
|
||||
fread(data->data(), elems, sizeof(drm_color_lut), f);
|
||||
|
||||
drm->pending.color_shaperlut_override = std::move(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool drm_set_color_sdr_gamut_wideness( struct drm_t *drm, float flVal )
|
||||
{
|
||||
if ( drm->pending.color_mgmt.sdrGamutWideness == flVal )
|
||||
return false;
|
||||
|
||||
drm->pending.color_mgmt.sdrGamutWideness = flVal;
|
||||
|
||||
return drm->pending.color_mgmt.enabled;
|
||||
}
|
||||
bool drm_set_color_nightmode( struct drm_t *drm, const nightmode_t &nightmode )
|
||||
{
|
||||
if ( drm->pending.color_mgmt.nightmode == nightmode )
|
||||
return false;
|
||||
|
||||
drm->pending.color_mgmt.nightmode = nightmode;
|
||||
|
||||
return drm->pending.color_mgmt.enabled;
|
||||
}
|
||||
bool drm_set_color_mgmt_enabled( struct drm_t *drm, bool bEnabled )
|
||||
{
|
||||
if ( drm->pending.color_mgmt.enabled == bEnabled )
|
||||
return false;
|
||||
|
||||
drm->pending.color_mgmt.enabled = bEnabled;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void drm_set_vrr_enabled(struct drm_t *drm, bool enabled)
|
||||
{
|
||||
drm->wants_vrr_enabled = enabled;
|
||||
|
@ -2452,123 +2298,36 @@ drm_screen_type drm_get_screen_type(struct drm_t *drm)
|
|||
return drm_get_connector_type(drm->connector->connector);
|
||||
}
|
||||
|
||||
bool drm_update_lut3d_override(struct drm_t *drm)
|
||||
{
|
||||
if ( drm->crtc == nullptr || !drm->crtc->lut3d_size )
|
||||
return true;
|
||||
|
||||
bool dirty = false;
|
||||
|
||||
if (drm->pending.color_lut3d_override != drm->current.color_lut3d_override)
|
||||
dirty = true;
|
||||
|
||||
if (!dirty)
|
||||
return true;
|
||||
|
||||
// Don't actually check for this, it's a lot of values...
|
||||
// Just check if it's empty or missing.
|
||||
bool identity =
|
||||
!drm->pending.color_lut3d_override ||
|
||||
drm->pending.color_lut3d_override->empty();
|
||||
|
||||
if (identity)
|
||||
{
|
||||
for ( uint32_t i = 0; i < ColorHelpers_EOTFCount; i++ )
|
||||
drm->pending.lut3d_id[i] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t blob_id = 0;
|
||||
if (drmModeCreatePropertyBlob(drm->fd, drm->pending.color_lut3d_override->data(),
|
||||
sizeof(drm_color_lut) * drm->pending.color_lut3d_override->size(), &blob_id) != 0) {
|
||||
drm_log.errorf_errno("Unable to create LUT3D property blob");
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( uint32_t i = 0; i < ColorHelpers_EOTFCount; i++ )
|
||||
drm->pending.lut3d_id[i] = blob_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool drm_update_shaperlut_override(struct drm_t *drm)
|
||||
{
|
||||
if ( drm->crtc == nullptr || !drm->crtc->shaperlut_size )
|
||||
return true;
|
||||
|
||||
bool dirty = false;
|
||||
|
||||
if (drm->pending.color_shaperlut_override != drm->current.color_shaperlut_override)
|
||||
dirty = true;
|
||||
|
||||
if (!dirty)
|
||||
return true;
|
||||
|
||||
// Don't actually check for this, it's a lot of values...
|
||||
// Just check if it's empty or missing.
|
||||
bool identity =
|
||||
!drm->pending.color_shaperlut_override ||
|
||||
drm->pending.color_shaperlut_override->empty();
|
||||
|
||||
if (identity)
|
||||
{
|
||||
for ( uint32_t i = 0; i < ColorHelpers_EOTFCount; i++ )
|
||||
drm->pending.shaperlut_id[i] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t blob_id = 0;
|
||||
if (drmModeCreatePropertyBlob(drm->fd, drm->pending.color_shaperlut_override->data(),
|
||||
sizeof(drm_color_lut) * drm->pending.color_shaperlut_override->size(), &blob_id) != 0) {
|
||||
drm_log.errorf_errno("Unable to create SHAPERLUT property blob");
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( uint32_t i = 0; i < ColorHelpers_EOTFCount; i++ )
|
||||
drm->pending.shaperlut_id[i] = blob_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool drm_update_color_mgmt(struct drm_t *drm)
|
||||
{
|
||||
if ( !drm->crtc || !drm->connector || !drm->crtc->shaperlut_size || !drm->crtc->lut3d_size )
|
||||
return true;
|
||||
|
||||
// update pending native display colorimetry
|
||||
drm->pending.color_mgmt.nativeDisplayColorimetry = drm->connector->metadata.colorimetry;
|
||||
|
||||
// check if any part of our color mgmt stack is dirty
|
||||
if (drm->pending.color_mgmt == drm->current.color_mgmt)
|
||||
if ( g_ColorMgmt.serial == drm->current.color_mgmt_serial )
|
||||
return true;
|
||||
|
||||
const displaycolorimetry_t& nativeDisplayOutput = drm->pending.color_mgmt.nativeDisplayColorimetry;
|
||||
const float flSDRGamutWideness = drm->pending.color_mgmt.sdrGamutWideness;
|
||||
|
||||
displaycolorimetry_t syntheticInputColorimetry{};
|
||||
colormapping_t syntheticInputColorMapping{};
|
||||
generateSyntheticInputColorimetry( &syntheticInputColorimetry, &syntheticInputColorMapping, flSDRGamutWideness, nativeDisplayOutput );
|
||||
|
||||
std::vector<uint16_t> lut3d;
|
||||
uint32_t nLutEdgeSize3d = 17;//drm->crtc->lut3d_size; // need to cube root
|
||||
lut3d.resize( nLutEdgeSize3d*nLutEdgeSize3d*nLutEdgeSize3d*4 );
|
||||
|
||||
std::vector<uint16_t> lut1d;
|
||||
uint32_t nLutSize1d = 4096;//drm->crtc->shaperlut_size;
|
||||
lut1d.resize( nLutSize1d*4 );
|
||||
drm->pending.color_mgmt_serial = g_ColorMgmt.serial;
|
||||
|
||||
for ( uint32_t i = 0; i < ColorHelpers_EOTFCount; i++ )
|
||||
{
|
||||
EOTF planeEOTF = static_cast<EOTF>( i );
|
||||
calcColorTransform( &lut1d[0], nLutSize1d, &lut3d[0], nLutEdgeSize3d, syntheticInputColorimetry, nativeDisplayOutput, syntheticInputColorMapping, drm->pending.color_mgmt.nightmode, planeEOTF );
|
||||
drm->pending.shaperlut_id[ i ] = 0;
|
||||
drm->pending.lut3d_id[ i ] = 0;
|
||||
}
|
||||
|
||||
for ( uint32_t i = 0; i < ColorHelpers_EOTFCount; i++ )
|
||||
{
|
||||
if ( g_ColorMgmtLuts[i].lut1d.empty() || g_ColorMgmtLuts[i].lut3d.empty() )
|
||||
continue;
|
||||
|
||||
uint32_t shaper_blob_id = 0;
|
||||
if (drmModeCreatePropertyBlob(drm->fd, lut1d.data(), sizeof(uint16_t) * lut1d.size(), &shaper_blob_id) != 0) {
|
||||
if (drmModeCreatePropertyBlob(drm->fd, g_ColorMgmtLuts[i].lut1d.data(), sizeof(uint16_t) * g_ColorMgmtLuts[i].lut1d.size(), &shaper_blob_id) != 0) {
|
||||
drm_log.errorf_errno("Unable to create SHAPERLUT property blob");
|
||||
return false;
|
||||
}
|
||||
drm->pending.shaperlut_id[ i ] = shaper_blob_id;
|
||||
|
||||
uint32_t lut3d_blob_id = 0;
|
||||
if (drmModeCreatePropertyBlob(drm->fd, lut3d.data(), sizeof(uint16_t) * lut3d.size(), &lut3d_blob_id) != 0) {
|
||||
if (drmModeCreatePropertyBlob(drm->fd, g_ColorMgmtLuts[i].lut3d.data(), sizeof(uint16_t) * g_ColorMgmtLuts[i].lut3d.size(), &lut3d_blob_id) != 0) {
|
||||
drm_log.errorf_errno("Unable to create LUT3D property blob");
|
||||
return false;
|
||||
}
|
||||
|
@ -2805,3 +2564,11 @@ bool drm_supports_color_mgmt(struct drm_t *drm)
|
|||
// TODO: hook up
|
||||
return true;
|
||||
}
|
||||
|
||||
const displaycolorimetry_t &drm_get_native_colorimetry(struct drm_t *drm)
|
||||
{
|
||||
if ( !drm || !drm->connector )
|
||||
return displaycolorimetry_709_gamma22;
|
||||
|
||||
return drm->connector->metadata.colorimetry;
|
||||
}
|
||||
|
|
27
src/drm.hpp
27
src/drm.hpp
|
@ -7,6 +7,7 @@
|
|||
#include <assert.h>
|
||||
#include <drm_fourcc.h>
|
||||
#include <drm_mode.h>
|
||||
|
||||
#include "color_helpers.h"
|
||||
|
||||
// Josh: Okay whatever, this header isn't
|
||||
|
@ -180,16 +181,6 @@ enum drm_valve1_transfer_function {
|
|||
DRM_VALVE1_TRANSFER_FUNCTION_MAX,
|
||||
};
|
||||
|
||||
struct gamescope_color_mgmt_t
|
||||
{
|
||||
bool enabled;
|
||||
nightmode_t nightmode;
|
||||
float sdrGamutWideness; // user property to widen gamut
|
||||
displaycolorimetry_t nativeDisplayColorimetry;
|
||||
|
||||
bool operator <=> (const gamescope_color_mgmt_t&) const = default;
|
||||
};
|
||||
|
||||
struct drm_t {
|
||||
int fd;
|
||||
|
||||
|
@ -225,17 +216,11 @@ struct drm_t {
|
|||
|
||||
struct {
|
||||
uint32_t mode_id;
|
||||
uint32_t gamma_lut_id;
|
||||
uint32_t degamma_lut_id;
|
||||
uint32_t ctm_id;
|
||||
uint32_t color_mgmt_serial;
|
||||
uint32_t lut3d_id[ ColorHelpers_EOTFCount ];
|
||||
uint32_t shaperlut_id[ ColorHelpers_EOTFCount ];
|
||||
drm_valve1_transfer_function regamma_tf = DRM_VALVE1_TRANSFER_FUNCTION_DEFAULT;
|
||||
enum drm_screen_type screen_type = DRM_SCREEN_TYPE_INTERNAL;
|
||||
bool vrr_enabled = false;
|
||||
std::shared_ptr<std::vector<drm_color_lut>> color_lut3d_override;
|
||||
std::shared_ptr<std::vector<drm_color_lut>> color_shaperlut_override;
|
||||
gamescope_color_mgmt_t color_mgmt{};
|
||||
} current, pending;
|
||||
bool wants_vrr_enabled = false;
|
||||
|
||||
|
@ -312,8 +297,6 @@ 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_refresh( struct drm_t *drm, int refresh );
|
||||
bool drm_set_resolution( struct drm_t *drm, int width, int height );
|
||||
bool drm_update_lut3d_override(struct drm_t *drm);
|
||||
bool drm_update_shaperlut_override(struct drm_t *drm);
|
||||
bool drm_update_color_mgmt(struct drm_t *drm);
|
||||
bool drm_update_vrr_state(struct drm_t *drm);
|
||||
drm_screen_type drm_get_screen_type(struct drm_t *drm);
|
||||
|
@ -334,11 +317,7 @@ const char *drm_get_device_name(struct drm_t *drm);
|
|||
std::pair<uint32_t, uint32_t> drm_get_connector_identifier(struct drm_t *drm);
|
||||
void drm_set_hdr_state(struct drm_t *drm, bool enabled);
|
||||
|
||||
bool drm_set_3dlut(struct drm_t *drm, const char *path);
|
||||
bool drm_set_shaperlut(struct drm_t *drm, const char *path);
|
||||
bool drm_set_color_sdr_gamut_wideness( struct drm_t *drm, float flVal );
|
||||
bool drm_set_color_nightmode( struct drm_t *drm, const nightmode_t &nightmode );
|
||||
bool drm_set_color_mgmt_enabled( struct drm_t *drm, bool bEnabled );
|
||||
const displaycolorimetry_t &drm_get_native_colorimetry(struct drm_t *drm);
|
||||
|
||||
extern bool g_bSupportsAsyncFlips;
|
||||
|
||||
|
|
|
@ -336,3 +336,38 @@ bool vulkan_supports_modifiers(void);
|
|||
struct wlr_renderer *vulkan_renderer_create( void );
|
||||
|
||||
using mat3x4 = std::array<std::array<float, 4>, 3>;
|
||||
|
||||
#include "color_helpers.h"
|
||||
|
||||
struct gamescope_color_mgmt_t
|
||||
{
|
||||
bool enabled;
|
||||
bool hasOverrides;
|
||||
nightmode_t nightmode;
|
||||
float sdrGamutWideness; // user property to widen gamut
|
||||
displaycolorimetry_t nativeDisplayColorimetry;
|
||||
|
||||
bool operator <=> (const gamescope_color_mgmt_t&) const = default;
|
||||
};
|
||||
|
||||
struct gamescope_color_mgmt_luts
|
||||
{
|
||||
std::vector<uint16_t> lut3d;
|
||||
std::vector<uint16_t> lut1d;
|
||||
|
||||
void reset()
|
||||
{
|
||||
lut3d.clear();
|
||||
lut1d.clear();
|
||||
}
|
||||
};
|
||||
|
||||
struct gamescope_color_mgmt_tracker_t
|
||||
{
|
||||
gamescope_color_mgmt_t pending{};
|
||||
gamescope_color_mgmt_t current{};
|
||||
uint32_t serial{};
|
||||
};
|
||||
|
||||
extern gamescope_color_mgmt_tracker_t g_ColorMgmt;
|
||||
extern gamescope_color_mgmt_luts g_ColorMgmtLuts[ ColorHelpers_EOTFCount ];
|
||||
|
|
|
@ -97,10 +97,172 @@
|
|||
#define GPUVIS_TRACE_IMPLEMENTATION
|
||||
#include "gpuvis_trace_utils.h"
|
||||
|
||||
///
|
||||
// Color Mgmt
|
||||
//
|
||||
|
||||
gamescope_color_mgmt_tracker_t g_ColorMgmt{};
|
||||
|
||||
static gamescope_color_mgmt_luts g_ColorMgmtLutsOverride[ ColorHelpers_EOTFCount ];
|
||||
gamescope_color_mgmt_luts g_ColorMgmtLuts[ ColorHelpers_EOTFCount ];
|
||||
|
||||
static void
|
||||
update_color_mgmt()
|
||||
{
|
||||
// update pending native display colorimetry
|
||||
if ( !BIsNested() )
|
||||
{
|
||||
g_ColorMgmt.pending.nativeDisplayColorimetry = drm_get_native_colorimetry( &g_DRM );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ColorMgmt.pending.nativeDisplayColorimetry = displaycolorimetry_709_gamma22;
|
||||
}
|
||||
|
||||
// check if any part of our color mgmt stack is dirty
|
||||
if ( g_ColorMgmt.pending == g_ColorMgmt.current && g_ColorMgmt.serial != 0 )
|
||||
return;
|
||||
|
||||
if (g_ColorMgmt.pending.enabled)
|
||||
{
|
||||
const displaycolorimetry_t& nativeDisplayOutput = g_ColorMgmt.pending.nativeDisplayColorimetry;
|
||||
const float flSDRGamutWideness = g_ColorMgmt.pending.sdrGamutWideness;
|
||||
|
||||
displaycolorimetry_t syntheticInputColorimetry{};
|
||||
colormapping_t syntheticInputColorMapping{};
|
||||
generateSyntheticInputColorimetry( &syntheticInputColorimetry, &syntheticInputColorMapping, flSDRGamutWideness, nativeDisplayOutput );
|
||||
|
||||
std::vector<uint16_t> lut3d;
|
||||
uint32_t nLutEdgeSize3d = 17;
|
||||
lut3d.resize( nLutEdgeSize3d*nLutEdgeSize3d*nLutEdgeSize3d*4 );
|
||||
|
||||
std::vector<uint16_t> lut1d;
|
||||
uint32_t nLutSize1d = 4096;
|
||||
lut1d.resize( nLutSize1d*4 );
|
||||
|
||||
for ( uint32_t i = 0; i < ColorHelpers_EOTFCount; i++ )
|
||||
{
|
||||
EOTF planeEOTF = static_cast<EOTF>( i );
|
||||
calcColorTransform( &lut1d[0], nLutSize1d, &lut3d[0], nLutEdgeSize3d, syntheticInputColorimetry, nativeDisplayOutput, syntheticInputColorMapping, g_ColorMgmt.pending.nightmode, planeEOTF );
|
||||
|
||||
if ( g_ColorMgmt.pending.hasOverrides )
|
||||
g_ColorMgmtLuts[i] = g_ColorMgmtLutsOverride[i];
|
||||
else if ( !lut3d.empty() && !lut1d.empty() )
|
||||
g_ColorMgmtLuts[i] = gamescope_color_mgmt_luts{ lut3d, lut1d };
|
||||
else
|
||||
g_ColorMgmtLuts[i].reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( uint32_t i = 0; i < ColorHelpers_EOTFCount; i++ )
|
||||
g_ColorMgmtLuts[i].reset();
|
||||
}
|
||||
|
||||
static uint32_t s_NextColorMgmtSerial = 0;
|
||||
|
||||
g_ColorMgmt.serial = ++s_NextColorMgmtSerial;
|
||||
g_ColorMgmt.current = g_ColorMgmt.pending;
|
||||
}
|
||||
|
||||
bool set_color_sdr_gamut_wideness( float flVal )
|
||||
{
|
||||
if ( g_ColorMgmt.pending.sdrGamutWideness == flVal )
|
||||
return false;
|
||||
|
||||
g_ColorMgmt.pending.sdrGamutWideness = flVal;
|
||||
|
||||
return g_ColorMgmt.pending.enabled;
|
||||
}
|
||||
bool set_color_nightmode( const nightmode_t &nightmode )
|
||||
{
|
||||
if ( g_ColorMgmt.pending.nightmode == nightmode )
|
||||
return false;
|
||||
|
||||
g_ColorMgmt.pending.nightmode = nightmode;
|
||||
|
||||
return g_ColorMgmt.pending.enabled;
|
||||
}
|
||||
bool set_color_mgmt_enabled( bool bEnabled )
|
||||
{
|
||||
if ( g_ColorMgmt.pending.enabled == bEnabled )
|
||||
return false;
|
||||
|
||||
g_ColorMgmt.pending.enabled = bEnabled;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool set_color_3dlut_override(const char *path)
|
||||
{
|
||||
bool had_lut = !g_ColorMgmtLutsOverride[0].lut3d.empty();
|
||||
|
||||
g_ColorMgmtLutsOverride[0].lut3d.clear();
|
||||
g_ColorMgmt.pending.hasOverrides = !g_ColorMgmtLutsOverride[0].lut1d.empty() && g_ColorMgmtLutsOverride[0].lut3d.empty();
|
||||
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
return had_lut;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
size_t elems = fsize / sizeof(uint16_t);
|
||||
|
||||
if (elems == 0) {
|
||||
return had_lut;
|
||||
}
|
||||
|
||||
auto data = std::vector<uint16_t>(elems);
|
||||
fread(data.data(), elems, sizeof(uint16_t), f);
|
||||
|
||||
g_ColorMgmtLutsOverride[0].lut3d = std::move(data);
|
||||
g_ColorMgmt.pending.hasOverrides = !g_ColorMgmtLutsOverride[0].lut1d.empty() && g_ColorMgmtLutsOverride[0].lut3d.empty();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool set_color_shaperlut_override(const char *path)
|
||||
{
|
||||
bool had_lut = !g_ColorMgmtLutsOverride[0].lut1d.empty();
|
||||
|
||||
g_ColorMgmtLutsOverride[0].lut1d.clear();
|
||||
g_ColorMgmt.pending.hasOverrides = !g_ColorMgmtLutsOverride[0].lut1d.empty() && g_ColorMgmtLutsOverride[0].lut3d.empty();
|
||||
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
return had_lut;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long fsize = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
size_t elems = fsize / sizeof(uint16_t);
|
||||
|
||||
if (elems == 0) {
|
||||
return had_lut;
|
||||
}
|
||||
|
||||
auto data = std::vector<uint16_t>(elems);
|
||||
fread(data.data(), elems, sizeof(uint16_t), f);
|
||||
|
||||
g_ColorMgmtLutsOverride[0].lut1d = std::move(data);
|
||||
g_ColorMgmt.pending.hasOverrides = !g_ColorMgmtLutsOverride[0].lut1d.empty() && g_ColorMgmtLutsOverride[0].lut3d.empty();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
extern float g_flLinearToNits;
|
||||
extern float g_flHDRItmSdrNits;
|
||||
extern float g_flHDRItmTargetNits;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
const uint32_t WS_OVERLAPPED = 0x00000000u;
|
||||
const uint32_t WS_POPUP = 0x80000000u;
|
||||
const uint32_t WS_CHILD = 0x40000000u;
|
||||
|
@ -1729,6 +1891,8 @@ paint_all(bool async)
|
|||
|
||||
static long long int paintID = 0;
|
||||
|
||||
update_color_mgmt();
|
||||
|
||||
paintID++;
|
||||
gpuvis_trace_begin_ctx_printf( paintID, "paint_all" );
|
||||
steamcompmgr_win_t *w;
|
||||
|
@ -4689,19 +4853,19 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
|
|||
if ( ev->atom == ctx->atoms.gamescopeColorLut3DOverride )
|
||||
{
|
||||
std::string path = get_string_prop( ctx, ctx->root, ctx->atoms.gamescopeColorLut3DOverride );
|
||||
if ( drm_set_3dlut( &g_DRM, path.c_str() ) )
|
||||
if ( set_color_3dlut_override( path.c_str() ) )
|
||||
hasRepaint = true;
|
||||
}
|
||||
if ( ev->atom == ctx->atoms.gamescopeColorShaperLutOverride )
|
||||
{
|
||||
std::string path = get_string_prop( ctx, ctx->root, ctx->atoms.gamescopeColorShaperLutOverride );
|
||||
if ( drm_set_shaperlut( &g_DRM, path.c_str() ) )
|
||||
if ( set_color_shaperlut_override( path.c_str() ) )
|
||||
hasRepaint = true;
|
||||
}
|
||||
if ( ev->atom == ctx->atoms.gamescopeColorSDRGamutWideness )
|
||||
{
|
||||
uint32_t val = get_prop(ctx, ctx->root, ctx->atoms.gamescopeColorSDRGamutWideness, 0);
|
||||
if ( drm_set_color_sdr_gamut_wideness( &g_DRM, bit_cast<float>(val) ) )
|
||||
if ( set_color_sdr_gamut_wideness( bit_cast<float>(val) ) )
|
||||
hasRepaint = true;
|
||||
}
|
||||
if ( ev->atom == ctx->atoms.gamescopeColorNightMode )
|
||||
|
@ -4722,13 +4886,13 @@ handle_property_notify(xwayland_ctx_t *ctx, XPropertyEvent *ev)
|
|||
nightmode.hue = vec[1];
|
||||
nightmode.saturation = vec[2];
|
||||
|
||||
if ( drm_set_color_nightmode( &g_DRM, nightmode ) )
|
||||
if ( set_color_nightmode( nightmode ) )
|
||||
hasRepaint = true;
|
||||
}
|
||||
if ( ev->atom == ctx->atoms.gamescopeColorManagementDisable )
|
||||
{
|
||||
uint32_t val = get_prop(ctx, ctx->root, ctx->atoms.gamescopeColorManagementDisable, 0);
|
||||
if ( drm_set_color_mgmt_enabled( &g_DRM, !val ) )
|
||||
if ( set_color_mgmt_enabled( !val ) )
|
||||
hasRepaint = true;
|
||||
}
|
||||
if (ev->atom == ctx->atoms.gamescopeCreateXWaylandServer)
|
||||
|
@ -6151,6 +6315,9 @@ steamcompmgr_main(int argc, char **argv)
|
|||
alwaysComposite = true;
|
||||
}
|
||||
|
||||
// Enable color mgmt by default.
|
||||
g_ColorMgmt.pending.enabled = true;
|
||||
|
||||
currentOutputWidth = g_nPreferredOutputWidth;
|
||||
currentOutputHeight = g_nPreferredOutputHeight;
|
||||
|
||||
|
|
Loading…
Reference in a new issue