mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-07-20 14:22:00 +00:00
[client] wayland: use the locally configured white level for SDR
This commit is contained in:
@@ -89,6 +89,7 @@ static void applyHDRPending(void)
|
||||
params.minDisplayLuminance,
|
||||
params.maxCLL,
|
||||
params.maxFALL,
|
||||
params.referenceWhiteLevel,
|
||||
params.pq,
|
||||
params.metadata);
|
||||
}
|
||||
@@ -162,9 +163,6 @@ static void activateReadyHDRImageDescription(void)
|
||||
wp_color_management_surface_v1_set_image_description(
|
||||
wlWm.colorSurface, desc,
|
||||
WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL);
|
||||
if (wlWm.hdrImageDescPQ)
|
||||
atomic_store(&wlWm.hdrActivePQWhiteLevel,
|
||||
wlWm.hdrImageDescWhiteLevel);
|
||||
atomic_store(&wlWm.hdrActivePQ, wlWm.hdrImageDescPQ);
|
||||
atomic_store(&wlWm.hdrActive, true);
|
||||
|
||||
@@ -368,7 +366,7 @@ static bool hdrTargetLuminanceContained(uint32_t minLuminance,
|
||||
void waylandSetHDRImageDescription(const uint16_t displayPrimary[3][2],
|
||||
const uint16_t whitePoint[2], uint32_t maxDisplayLuminance,
|
||||
uint32_t minDisplayLuminance, uint32_t maxCLL, uint32_t maxFALL,
|
||||
bool hdrPQ, bool hdrMetadata)
|
||||
uint32_t referenceWhiteLevel, bool hdrPQ, bool hdrMetadata)
|
||||
{
|
||||
if (!wlWm.colorManager)
|
||||
return;
|
||||
@@ -484,17 +482,22 @@ void waylandSetHDRImageDescription(const uint16_t displayPrimary[3][2],
|
||||
wlWm.hdrImageCreator,
|
||||
WP_COLOR_MANAGER_V1_TRANSFER_FUNCTION_ST2084_PQ);
|
||||
|
||||
wlWm.hdrImageDescWhiteLevel = wlWm.cmHasLuminances ?
|
||||
atomic_load(&wlWm.hdrPQWhiteLevel) : HDR_PQ_DEFAULT_WHITE_LEVEL;
|
||||
const uint32_t sourceWhiteLevel = referenceWhiteLevel ?
|
||||
referenceWhiteLevel : HDR_PQ_DEFAULT_WHITE_LEVEL;
|
||||
|
||||
// The primary colour volume describes the PQ encoding itself. Mastering
|
||||
// display luminances are target-volume metadata and are set separately.
|
||||
// Reference white describes the guest image content; the Wayland output
|
||||
// reference white is used independently when composing local overlays.
|
||||
if (wlWm.cmHasLuminances)
|
||||
wp_image_description_creator_params_v1_set_luminances(
|
||||
wlWm.hdrImageCreator,
|
||||
HDR_PQ_MIN_LUMINANCE,
|
||||
HDR_PQ_MAX_LUMINANCE,
|
||||
wlWm.hdrImageDescWhiteLevel);
|
||||
sourceWhiteLevel);
|
||||
else if (sourceWhiteLevel != HDR_PQ_DEFAULT_WHITE_LEVEL)
|
||||
DEBUG_WARN("Compositor cannot accept the guest reference white level; "
|
||||
"using the PQ default");
|
||||
|
||||
// KVMFR uses the ST 2086/DXGI scale of 50,000 units per coordinate while
|
||||
// color-management-v1 uses 1,000,000 units per coordinate.
|
||||
@@ -576,15 +579,17 @@ void waylandSetHDRImageDescription(const uint16_t displayPrimary[3][2],
|
||||
LG_UNLOCK(wlWm.hdrLock);
|
||||
|
||||
DEBUG_INFO("HDR image description requested (%s, %s, "
|
||||
"maxLum:%u cd/m² minLum:%u (0.0001 cd/m²) maxCLL:%u maxFALL:%u)",
|
||||
"referenceWhite:%u cd/m² maxLum:%u cd/m² "
|
||||
"minLum:%u (0.0001 cd/m²) maxCLL:%u maxFALL:%u)",
|
||||
hdrPQ ? "PQ" : "scRGB", hdrPQ ? "BT.2020" : "sRGB",
|
||||
maxDisplayLuminance, minDisplayLuminance, maxCLL, maxFALL);
|
||||
sourceWhiteLevel, maxDisplayLuminance, minDisplayLuminance,
|
||||
maxCLL, maxFALL);
|
||||
}
|
||||
|
||||
bool waylandRequestHDR(const uint16_t displayPrimary[3][2],
|
||||
const uint16_t whitePoint[2], uint32_t maxDisplayLuminance,
|
||||
uint32_t minDisplayLuminance, uint32_t maxCLL, uint32_t maxFALL,
|
||||
bool hdrPQ, bool hdrMetadata)
|
||||
uint32_t referenceWhiteLevel, bool hdrPQ, bool hdrMetadata)
|
||||
{
|
||||
if (!atomic_load_explicit(&wlWm.cmFeaturesDone, memory_order_acquire))
|
||||
return false;
|
||||
@@ -600,16 +605,18 @@ bool waylandRequestHDR(const uint16_t displayPrimary[3][2],
|
||||
atomic_store(&wlWm.hdrRequested, true);
|
||||
|
||||
LG_LOCK(wlWm.pendingHDRLock);
|
||||
wlWm.pendingHDR.pq = hdrPQ;
|
||||
wlWm.pendingHDR.metadata = hdrMetadata;
|
||||
wlWm.pendingHDR.pq = hdrPQ;
|
||||
wlWm.pendingHDR.metadata = hdrMetadata;
|
||||
wlWm.pendingHDR.maxDisplayLuminance = maxDisplayLuminance;
|
||||
wlWm.pendingHDR.minDisplayLuminance = minDisplayLuminance;
|
||||
wlWm.pendingHDR.maxCLL = maxCLL;
|
||||
wlWm.pendingHDR.maxFALL = maxFALL;
|
||||
wlWm.pendingHDR.referenceWhiteLevel = referenceWhiteLevel;
|
||||
memcpy(wlWm.pendingHDR.displayPrimary, displayPrimary,
|
||||
sizeof(wlWm.pendingHDR.displayPrimary));
|
||||
memcpy(wlWm.pendingHDR.whitePoint, whitePoint,
|
||||
sizeof(wlWm.pendingHDR.whitePoint));
|
||||
wlWm.pendingHDR.maxDisplayLuminance = maxDisplayLuminance;
|
||||
wlWm.pendingHDR.minDisplayLuminance = minDisplayLuminance;
|
||||
wlWm.pendingHDR.maxCLL = maxCLL;
|
||||
wlWm.pendingHDR.maxFALL = maxFALL;
|
||||
|
||||
wlWm.pendingHDRAction = WAYLAND_HDR_PENDING_APPLY;
|
||||
LG_UNLOCK(wlWm.pendingHDRLock);
|
||||
return true;
|
||||
|
||||
@@ -82,12 +82,6 @@ void waylandOutputUpdateHDRWhiteLevel(void)
|
||||
if ((oldPQ != pqWhite || oldScRGB != scRGBWhite) && wlWm.frameEvent)
|
||||
{
|
||||
DEBUG_INFO("Wayland output reference white: %u cd/m²", pqWhite);
|
||||
if (atomic_load(&wlWm.hdrRequested))
|
||||
{
|
||||
LG_LOCK(wlWm.pendingHDRLock);
|
||||
wlWm.pendingHDRAction = WAYLAND_HDR_PENDING_APPLY;
|
||||
LG_UNLOCK(wlWm.pendingHDRLock);
|
||||
}
|
||||
app_invalidateWindow(true);
|
||||
waylandStopWaitFrame();
|
||||
}
|
||||
|
||||
@@ -115,7 +115,6 @@ static bool waylandInit(const LG_DSInitParams params)
|
||||
atomic_init(&wlWm.cmCanDoHDR, false);
|
||||
atomic_init(&wlWm.hdrPQWhiteLevel, 203);
|
||||
atomic_init(&wlWm.hdrScRGBWhiteLevel, 80);
|
||||
atomic_init(&wlWm.hdrActivePQWhiteLevel, 203);
|
||||
|
||||
wlWm.display = wl_display_connect(NULL);
|
||||
if (!wlWm.display)
|
||||
@@ -236,12 +235,9 @@ static bool waylandGetProp(LG_DSProperty prop, void * ret)
|
||||
|
||||
if (prop == LG_DS_HDR_WHITE_LEVELS)
|
||||
{
|
||||
const bool activePQ = atomic_load(&wlWm.hdrActive) &&
|
||||
atomic_load(&wlWm.hdrActivePQ);
|
||||
*(LG_DSHDRWhiteLevels *)ret = (LG_DSHDRWhiteLevels)
|
||||
{
|
||||
.pq = activePQ ? atomic_load(&wlWm.hdrActivePQWhiteLevel) :
|
||||
atomic_load(&wlWm.hdrPQWhiteLevel),
|
||||
.pq = atomic_load(&wlWm.hdrPQWhiteLevel),
|
||||
.scRGB = atomic_load(&wlWm.hdrScRGBWhiteLevel),
|
||||
};
|
||||
return true;
|
||||
@@ -282,7 +278,7 @@ static bool waylandHDRCallback(const void * rendererFormat)
|
||||
return waylandRequestHDR(format->hdrDisplayPrimary, format->hdrWhitePoint,
|
||||
format->hdrMaxDisplayLuminance, format->hdrMinDisplayLuminance,
|
||||
format->hdrMaxContentLightLevel, format->hdrMaxFrameAverageLightLevel,
|
||||
format->hdrPQ, format->hdrMetadata);
|
||||
format->sdrWhiteLevel, format->hdrPQ, format->hdrMetadata);
|
||||
else
|
||||
waylandRequestClearHDR();
|
||||
return true;
|
||||
|
||||
@@ -116,6 +116,7 @@ struct WaylandHDRParameters
|
||||
uint32_t minDisplayLuminance;
|
||||
uint32_t maxCLL;
|
||||
uint32_t maxFALL;
|
||||
uint32_t referenceWhiteLevel;
|
||||
};
|
||||
|
||||
struct WaylandDSState
|
||||
@@ -222,11 +223,9 @@ struct WaylandDSState
|
||||
_Atomic(bool) hdrActivePQ;
|
||||
_Atomic(bool) hdrRequested;
|
||||
_Atomic(bool) hdrRequestedPQ;
|
||||
bool hdrImageDescPQ;
|
||||
bool hdrImageDescReady;
|
||||
uint32_t hdrImageDescWhiteLevel;
|
||||
_Atomic(uint32_t) hdrActivePQWhiteLevel;
|
||||
LG_Lock hdrLock;
|
||||
bool hdrImageDescPQ;
|
||||
bool hdrImageDescReady;
|
||||
LG_Lock hdrLock;
|
||||
|
||||
// wp_color_manager_v1 feature advertisement tracking.
|
||||
// Set to true after the done event for the color-manager has been received
|
||||
@@ -349,7 +348,7 @@ void waylandColorMgmtFree(void);
|
||||
void waylandSetHDRImageDescription(const uint16_t displayPrimary[3][2],
|
||||
const uint16_t whitePoint[2], uint32_t maxDisplayLuminance,
|
||||
uint32_t minDisplayLuminance, uint32_t maxCLL, uint32_t maxFALL,
|
||||
bool hdrPQ, bool hdrMetadata);
|
||||
uint32_t referenceWhiteLevel, bool hdrPQ, bool hdrMetadata);
|
||||
void waylandClearHDRImageDescription(void);
|
||||
|
||||
// Queue HDR change from any thread (applied in waylandEGLSwapBuffers).
|
||||
@@ -358,7 +357,7 @@ void waylandClearHDRImageDescription(void);
|
||||
bool waylandRequestHDR(const uint16_t displayPrimary[3][2],
|
||||
const uint16_t whitePoint[2], uint32_t maxDisplayLuminance,
|
||||
uint32_t minDisplayLuminance, uint32_t maxCLL, uint32_t maxFALL,
|
||||
bool hdrPQ, bool hdrMetadata);
|
||||
uint32_t referenceWhiteLevel, bool hdrPQ, bool hdrMetadata);
|
||||
void waylandRequestClearHDR(void);
|
||||
|
||||
// idle module
|
||||
|
||||
Reference in New Issue
Block a user