mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-07-20 22:32:01 +00:00
wayland: make HDR descriptions asynchronous
Publish HDR metadata through a locked request snapshot and wait for image-description readiness before using it. Commit encoding changes with matching content, preserve the active description during same-format metadata replacements, and handle creation failures without protocol errors.
This commit is contained in:
@@ -105,6 +105,23 @@ void waylandColorMgmtFree(void)
|
|||||||
if (!wlWm.colorManager)
|
if (!wlWm.colorManager)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (wlWm.hdrImageCreator)
|
||||||
|
{
|
||||||
|
wp_image_description_creator_params_v1_destroy(wlWm.hdrImageCreator);
|
||||||
|
wlWm.hdrImageCreator = NULL;
|
||||||
|
}
|
||||||
|
if (wlWm.hdrImageDesc)
|
||||||
|
{
|
||||||
|
wp_image_description_v1_destroy(wlWm.hdrImageDesc);
|
||||||
|
wlWm.hdrImageDesc = NULL;
|
||||||
|
}
|
||||||
|
wlWm.hdrImageDescReady = false;
|
||||||
|
if (wlWm.colorSurface)
|
||||||
|
{
|
||||||
|
wp_color_management_surface_v1_destroy(wlWm.colorSurface);
|
||||||
|
wlWm.colorSurface = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
wp_color_manager_v1_destroy(wlWm.colorManager);
|
wp_color_manager_v1_destroy(wlWm.colorManager);
|
||||||
wlWm.colorManager = NULL;
|
wlWm.colorManager = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,31 +72,32 @@ EGLDisplay waylandGetEGLDisplay(void)
|
|||||||
|
|
||||||
static void applyHDRPending(void)
|
static void applyHDRPending(void)
|
||||||
{
|
{
|
||||||
if (wlWm.pendingHDRApply)
|
enum WaylandHDRPendingAction action;
|
||||||
|
struct WaylandHDRParameters params;
|
||||||
|
|
||||||
|
LG_LOCK(wlWm.pendingHDRLock);
|
||||||
|
action = wlWm.pendingHDRAction;
|
||||||
|
params = wlWm.pendingHDR;
|
||||||
|
wlWm.pendingHDRAction = WAYLAND_HDR_PENDING_NONE;
|
||||||
|
LG_UNLOCK(wlWm.pendingHDRLock);
|
||||||
|
|
||||||
|
if (action == WAYLAND_HDR_PENDING_APPLY)
|
||||||
{
|
{
|
||||||
wlWm.pendingHDRApply = false;
|
|
||||||
atomic_thread_fence(memory_order_acquire);
|
|
||||||
waylandSetHDRImageDescription(
|
waylandSetHDRImageDescription(
|
||||||
wlWm.pendingHDRDisplayPrimary, wlWm.pendingHDRWhitePoint,
|
params.displayPrimary, params.whitePoint,
|
||||||
wlWm.pendingHDRMaxDisplayLuminance,
|
params.maxDisplayLuminance,
|
||||||
wlWm.pendingHDRMinDisplayLuminance,
|
params.minDisplayLuminance,
|
||||||
wlWm.pendingHDRMaxCLL,
|
params.maxCLL,
|
||||||
wlWm.pendingHDRMaxFALL,
|
params.maxFALL,
|
||||||
wlWm.pendingHDRPQ,
|
params.pq,
|
||||||
wlWm.pendingHDRMetadata);
|
params.metadata);
|
||||||
}
|
}
|
||||||
else if (wlWm.pendingHDRClear)
|
else if (action == WAYLAND_HDR_PENDING_CLEAR)
|
||||||
{
|
|
||||||
wlWm.pendingHDRClear = false;
|
|
||||||
waylandClearHDRImageDescription();
|
waylandClearHDRImageDescription();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void waylandClearHDRImageDescription(void)
|
void waylandClearHDRImageDescription(void)
|
||||||
{
|
{
|
||||||
if (!wlWm.hdrActive)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (wlWm.hdrImageCreator)
|
if (wlWm.hdrImageCreator)
|
||||||
{
|
{
|
||||||
wp_image_description_creator_params_v1_destroy(wlWm.hdrImageCreator);
|
wp_image_description_creator_params_v1_destroy(wlWm.hdrImageCreator);
|
||||||
@@ -107,16 +108,103 @@ void waylandClearHDRImageDescription(void)
|
|||||||
wp_image_description_v1_destroy(wlWm.hdrImageDesc);
|
wp_image_description_v1_destroy(wlWm.hdrImageDesc);
|
||||||
wlWm.hdrImageDesc = NULL;
|
wlWm.hdrImageDesc = NULL;
|
||||||
}
|
}
|
||||||
if (wlWm.colorSurface)
|
wlWm.hdrImageDescReady = false;
|
||||||
|
|
||||||
|
if (wlWm.colorSurface && atomic_load(&wlWm.hdrActive))
|
||||||
|
wp_color_management_surface_v1_unset_image_description(wlWm.colorSurface);
|
||||||
|
|
||||||
|
atomic_store(&wlWm.hdrActive, false);
|
||||||
|
DEBUG_INFO("HDR image description removed from surface");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hdrImageDescriptionReady(struct wp_image_description_v1 * desc)
|
||||||
|
{
|
||||||
|
if (desc != wlWm.hdrImageDesc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!wlWm.colorSurface)
|
||||||
{
|
{
|
||||||
wp_color_management_surface_v1_destroy(wlWm.colorSurface);
|
DEBUG_WARN("HDR image description became ready without a color surface");
|
||||||
wlWm.colorSurface = NULL;
|
wp_image_description_v1_destroy(desc);
|
||||||
|
wlWm.hdrImageDesc = NULL;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlWm.hdrActive = false;
|
// Defer attachment until just after the current surface commit. EGL can
|
||||||
DEBUG_INFO("HDR image description cleared");
|
// then switch to native HDR for the next render, and that native frame and
|
||||||
|
// its image description become active in the same following commit.
|
||||||
|
wlWm.hdrImageDescReady = true;
|
||||||
|
DEBUG_INFO("HDR image description is ready (%s)",
|
||||||
|
wlWm.hdrImageDescPQ ? "PQ" : "scRGB");
|
||||||
|
app_invalidateWindow(true);
|
||||||
|
waylandStopWaitFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void activateReadyHDRImageDescription(void)
|
||||||
|
{
|
||||||
|
if (!wlWm.hdrImageDesc || !wlWm.hdrImageDescReady || !wlWm.colorSurface)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct wp_image_description_v1 * desc = wlWm.hdrImageDesc;
|
||||||
|
wp_color_management_surface_v1_set_image_description(
|
||||||
|
wlWm.colorSurface, desc,
|
||||||
|
WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL);
|
||||||
|
atomic_store(&wlWm.hdrActivePQ, wlWm.hdrImageDescPQ);
|
||||||
|
atomic_store(&wlWm.hdrActive, true);
|
||||||
|
|
||||||
|
// set_image_description has copy semantics; the protocol object is no
|
||||||
|
// longer needed once it has been attached to the pending surface state.
|
||||||
|
wlWm.hdrImageDesc = NULL;
|
||||||
|
wlWm.hdrImageDescReady = false;
|
||||||
|
wp_image_description_v1_destroy(desc);
|
||||||
|
|
||||||
|
DEBUG_INFO("HDR image description pending next surface commit (%s)",
|
||||||
|
atomic_load(&wlWm.hdrActivePQ) ? "PQ" : "scRGB");
|
||||||
|
app_invalidateWindow(true);
|
||||||
|
waylandStopWaitFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hdrImageDescriptionFailed(void * data,
|
||||||
|
struct wp_image_description_v1 * desc, uint32_t cause, const char * message)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
if (desc != wlWm.hdrImageDesc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DEBUG_WARN("Failed to create HDR image description (cause:%u): %s",
|
||||||
|
cause, message);
|
||||||
|
wlWm.hdrImageDesc = NULL;
|
||||||
|
wlWm.hdrImageDescReady = false;
|
||||||
|
wp_image_description_v1_destroy(desc);
|
||||||
|
app_invalidateWindow(true);
|
||||||
|
waylandStopWaitFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hdrImageDescriptionReadyV1(void * data,
|
||||||
|
struct wp_image_description_v1 * desc, uint32_t identity)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
(void)identity;
|
||||||
|
hdrImageDescriptionReady(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hdrImageDescriptionReadyV2(void * data,
|
||||||
|
struct wp_image_description_v1 * desc, uint32_t identityHi,
|
||||||
|
uint32_t identityLo)
|
||||||
|
{
|
||||||
|
(void)data;
|
||||||
|
(void)identityHi;
|
||||||
|
(void)identityLo;
|
||||||
|
hdrImageDescriptionReady(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wp_image_description_v1_listener hdrImageDescListener =
|
||||||
|
{
|
||||||
|
.failed = hdrImageDescriptionFailed,
|
||||||
|
.ready = hdrImageDescriptionReadyV1,
|
||||||
|
.ready2 = hdrImageDescriptionReadyV2,
|
||||||
|
};
|
||||||
|
|
||||||
void waylandEGLSwapBuffers(EGLDisplay display, EGLSurface surface, const struct Rect * damage, int count)
|
void waylandEGLSwapBuffers(EGLDisplay display, EGLSurface surface, const struct Rect * damage, int count)
|
||||||
{
|
{
|
||||||
if (!wlWm.swapWithDamage.init)
|
if (!wlWm.swapWithDamage.init)
|
||||||
@@ -133,6 +221,7 @@ void waylandEGLSwapBuffers(EGLDisplay display, EGLSurface surface, const struct
|
|||||||
waylandPresentationFrame();
|
waylandPresentationFrame();
|
||||||
applyHDRPending();
|
applyHDRPending();
|
||||||
swapWithDamage(&wlWm.swapWithDamage, display, surface, damage, count);
|
swapWithDamage(&wlWm.swapWithDamage, display, surface, damage, count);
|
||||||
|
activateReadyHDRImageDescription();
|
||||||
|
|
||||||
if (wlWm.needsResize)
|
if (wlWm.needsResize)
|
||||||
{
|
{
|
||||||
@@ -242,7 +331,8 @@ void waylandSetHDRImageDescription(const uint16_t displayPrimary[3][2],
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up any previous description (allows re-application with updated metadata)
|
// Cancel only an in-flight replacement. The active surface description is
|
||||||
|
// retained until this replacement is ready.
|
||||||
if (wlWm.hdrImageCreator)
|
if (wlWm.hdrImageCreator)
|
||||||
{
|
{
|
||||||
wp_image_description_creator_params_v1_destroy(wlWm.hdrImageCreator);
|
wp_image_description_creator_params_v1_destroy(wlWm.hdrImageCreator);
|
||||||
@@ -253,13 +343,26 @@ void waylandSetHDRImageDescription(const uint16_t displayPrimary[3][2],
|
|||||||
wp_image_description_v1_destroy(wlWm.hdrImageDesc);
|
wp_image_description_v1_destroy(wlWm.hdrImageDesc);
|
||||||
wlWm.hdrImageDesc = NULL;
|
wlWm.hdrImageDesc = NULL;
|
||||||
}
|
}
|
||||||
if (wlWm.colorSurface)
|
wlWm.hdrImageDescReady = false;
|
||||||
|
// If the encoding changed, remove the old description in the same surface
|
||||||
|
// commit that presents the software-mapped transition frame.
|
||||||
|
if (atomic_load(&wlWm.hdrActive) &&
|
||||||
|
atomic_load(&wlWm.hdrActivePQ) != hdrPQ)
|
||||||
{
|
{
|
||||||
wp_color_management_surface_v1_destroy(wlWm.colorSurface);
|
wp_color_management_surface_v1_unset_image_description(wlWm.colorSurface);
|
||||||
wlWm.colorSurface = NULL;
|
atomic_store(&wlWm.hdrActive, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
wlWm.hdrActive = false;
|
if (!wlWm.colorSurface)
|
||||||
|
{
|
||||||
|
wlWm.colorSurface =
|
||||||
|
wp_color_manager_v1_get_surface(wlWm.colorManager, wlWm.surface);
|
||||||
|
if (!wlWm.colorSurface)
|
||||||
|
{
|
||||||
|
DEBUG_WARN("Failed to get color management surface");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
wlWm.hdrImageCreator =
|
wlWm.hdrImageCreator =
|
||||||
wp_color_manager_v1_create_parametric_creator(wlWm.colorManager);
|
wp_color_manager_v1_create_parametric_creator(wlWm.colorManager);
|
||||||
@@ -332,22 +435,12 @@ void waylandSetHDRImageDescription(const uint16_t displayPrimary[3][2],
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wlWm.colorSurface =
|
wlWm.hdrImageDescPQ = hdrPQ;
|
||||||
wp_color_manager_v1_get_surface(wlWm.colorManager, wlWm.surface);
|
wlWm.hdrImageDescReady = false;
|
||||||
if (!wlWm.colorSurface)
|
wp_image_description_v1_add_listener(
|
||||||
{
|
wlWm.hdrImageDesc, &hdrImageDescListener, NULL);
|
||||||
DEBUG_WARN("Failed to get color management surface");
|
|
||||||
wp_image_description_v1_destroy(wlWm.hdrImageDesc);
|
|
||||||
wlWm.hdrImageDesc = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wp_color_management_surface_v1_set_image_description(
|
DEBUG_INFO("HDR image description requested (%s, %s, "
|
||||||
wlWm.colorSurface, wlWm.hdrImageDesc,
|
|
||||||
WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL);
|
|
||||||
|
|
||||||
wlWm.hdrActive = true;
|
|
||||||
DEBUG_INFO("HDR image description set on surface (%s, %s, "
|
|
||||||
"maxLum:%u cd/m² minLum:%u (0.0001 cd/m²) maxCLL:%u maxFALL:%u)",
|
"maxLum:%u cd/m² minLum:%u (0.0001 cd/m²) maxCLL:%u maxFALL:%u)",
|
||||||
hdrPQ ? "PQ" : "scRGB", hdrPQ ? "BT.2020" : "sRGB",
|
hdrPQ ? "PQ" : "scRGB", hdrPQ ? "BT.2020" : "sRGB",
|
||||||
maxDisplayLuminance, minDisplayLuminance, maxCLL, maxFALL);
|
maxDisplayLuminance, minDisplayLuminance, maxCLL, maxFALL);
|
||||||
@@ -369,31 +462,31 @@ bool waylandRequestHDR(const uint16_t displayPrimary[3][2],
|
|||||||
if (!hdrPQ && !wlWm.cmHasPrimariesSRGB)
|
if (!hdrPQ && !wlWm.cmHasPrimariesSRGB)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wlWm.pendingHDRPQ = hdrPQ;
|
atomic_store(&wlWm.hdrRequestedPQ, hdrPQ);
|
||||||
wlWm.pendingHDRMetadata = hdrMetadata;
|
atomic_store(&wlWm.hdrRequested, true);
|
||||||
|
|
||||||
// Write all metadata before setting the apply flag to ensure the
|
LG_LOCK(wlWm.pendingHDRLock);
|
||||||
// render thread sees the complete HDR metadata when it observes
|
wlWm.pendingHDR.pq = hdrPQ;
|
||||||
// pendingHDRApply == true.
|
wlWm.pendingHDR.metadata = hdrMetadata;
|
||||||
memcpy(wlWm.pendingHDRDisplayPrimary, displayPrimary,
|
memcpy(wlWm.pendingHDR.displayPrimary, displayPrimary,
|
||||||
sizeof(wlWm.pendingHDRDisplayPrimary));
|
sizeof(wlWm.pendingHDR.displayPrimary));
|
||||||
memcpy(wlWm.pendingHDRWhitePoint, whitePoint,
|
memcpy(wlWm.pendingHDR.whitePoint, whitePoint,
|
||||||
sizeof(wlWm.pendingHDRWhitePoint));
|
sizeof(wlWm.pendingHDR.whitePoint));
|
||||||
wlWm.pendingHDRMaxDisplayLuminance = maxDisplayLuminance;
|
wlWm.pendingHDR.maxDisplayLuminance = maxDisplayLuminance;
|
||||||
wlWm.pendingHDRMinDisplayLuminance = minDisplayLuminance;
|
wlWm.pendingHDR.minDisplayLuminance = minDisplayLuminance;
|
||||||
wlWm.pendingHDRMaxCLL = maxCLL;
|
wlWm.pendingHDR.maxCLL = maxCLL;
|
||||||
wlWm.pendingHDRMaxFALL = maxFALL;
|
wlWm.pendingHDR.maxFALL = maxFALL;
|
||||||
|
wlWm.pendingHDRAction = WAYLAND_HDR_PENDING_APPLY;
|
||||||
wlWm.pendingHDRClear = false;
|
LG_UNLOCK(wlWm.pendingHDRLock);
|
||||||
atomic_thread_fence(memory_order_release);
|
|
||||||
wlWm.pendingHDRApply = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void waylandRequestClearHDR(void)
|
void waylandRequestClearHDR(void)
|
||||||
{
|
{
|
||||||
wlWm.pendingHDRClear = true;
|
atomic_store(&wlWm.hdrRequested, false);
|
||||||
wlWm.pendingHDRApply = false;
|
LG_LOCK(wlWm.pendingHDRLock);
|
||||||
|
wlWm.pendingHDRAction = WAYLAND_HDR_PENDING_CLEAR;
|
||||||
|
LG_UNLOCK(wlWm.pendingHDRLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_OPENGL
|
#ifdef ENABLE_OPENGL
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ static bool getCompositor(char * dst, size_t size)
|
|||||||
static bool waylandInit(const LG_DSInitParams params)
|
static bool waylandInit(const LG_DSInitParams params)
|
||||||
{
|
{
|
||||||
memset(&wlWm, 0, sizeof(wlWm));
|
memset(&wlWm, 0, sizeof(wlWm));
|
||||||
|
LG_LOCK_INIT(wlWm.pendingHDRLock);
|
||||||
wlWm.desktop = WL_Desktops[0];
|
wlWm.desktop = WL_Desktops[0];
|
||||||
wlWm.hdrWhiteLevels = (LG_DSHDRWhiteLevels)
|
wlWm.hdrWhiteLevels = (LG_DSHDRWhiteLevels)
|
||||||
{
|
{
|
||||||
@@ -211,6 +212,7 @@ static void waylandFree(void)
|
|||||||
waylandRegistryFree();
|
waylandRegistryFree();
|
||||||
waylandCursorFree();
|
waylandCursorFree();
|
||||||
wl_display_disconnect(wlWm.display);
|
wl_display_disconnect(wlWm.display);
|
||||||
|
LG_LOCK_FREE(wlWm.pendingHDRLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool waylandGetProp(LG_DSProperty prop, void * ret)
|
static bool waylandGetProp(LG_DSProperty prop, void * ret)
|
||||||
@@ -223,7 +225,10 @@ static bool waylandGetProp(LG_DSProperty prop, void * ret)
|
|||||||
|
|
||||||
if (prop == LG_DS_NATIVE_HDR)
|
if (prop == LG_DS_NATIVE_HDR)
|
||||||
{
|
{
|
||||||
*(bool *)ret = wlWm.cmCanDoHDR;
|
const bool active = atomic_load(&wlWm.hdrActive);
|
||||||
|
const bool requested = atomic_load(&wlWm.hdrRequested);
|
||||||
|
*(bool *)ret = active && requested &&
|
||||||
|
atomic_load(&wlWm.hdrActivePQ) == atomic_load(&wlWm.hdrRequestedPQ);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,25 @@ struct xkb_context;
|
|||||||
struct xkb_keymap;
|
struct xkb_keymap;
|
||||||
struct xkb_state;
|
struct xkb_state;
|
||||||
|
|
||||||
|
enum WaylandHDRPendingAction
|
||||||
|
{
|
||||||
|
WAYLAND_HDR_PENDING_NONE,
|
||||||
|
WAYLAND_HDR_PENDING_APPLY,
|
||||||
|
WAYLAND_HDR_PENDING_CLEAR,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WaylandHDRParameters
|
||||||
|
{
|
||||||
|
bool pq;
|
||||||
|
bool metadata;
|
||||||
|
uint16_t displayPrimary[3][2];
|
||||||
|
uint16_t whitePoint[2];
|
||||||
|
uint32_t maxDisplayLuminance;
|
||||||
|
uint32_t minDisplayLuminance;
|
||||||
|
uint32_t maxCLL;
|
||||||
|
uint32_t maxFALL;
|
||||||
|
};
|
||||||
|
|
||||||
struct WaylandDSState
|
struct WaylandDSState
|
||||||
{
|
{
|
||||||
bool pointerGrabbed;
|
bool pointerGrabbed;
|
||||||
@@ -189,8 +208,14 @@ struct WaylandDSState
|
|||||||
struct wp_image_description_v1 * hdrImageDesc;
|
struct wp_image_description_v1 * hdrImageDesc;
|
||||||
struct wp_image_description_creator_params_v1 * hdrImageCreator;
|
struct wp_image_description_creator_params_v1 * hdrImageCreator;
|
||||||
|
|
||||||
// Set to true when an HDR image description is active on the surface
|
// Active and requested encodings are atomic because getProp runs on the
|
||||||
bool hdrActive;
|
// renderer while description events are dispatched by Wayland.
|
||||||
|
_Atomic(bool) hdrActive;
|
||||||
|
_Atomic(bool) hdrActivePQ;
|
||||||
|
_Atomic(bool) hdrRequested;
|
||||||
|
_Atomic(bool) hdrRequestedPQ;
|
||||||
|
bool hdrImageDescPQ;
|
||||||
|
bool hdrImageDescReady;
|
||||||
|
|
||||||
// wp_color_manager_v1 feature advertisement tracking.
|
// wp_color_manager_v1 feature advertisement tracking.
|
||||||
// Set to true after the done event for the color-manager has been received
|
// Set to true after the done event for the color-manager has been received
|
||||||
@@ -215,19 +240,12 @@ struct WaylandDSState
|
|||||||
// set by the active desktop backend during shellInit
|
// set by the active desktop backend during shellInit
|
||||||
void * xdgToplevel;
|
void * xdgToplevel;
|
||||||
|
|
||||||
// Pending HDR format to apply (set by frame thread, applied in swap buffers).
|
// Pending HDR format is published by the frame thread and consumed by the
|
||||||
// pendingHDRApply and pendingHDRClear are accessed from multiple threads
|
// render thread. Keep the action and all metadata in one locked snapshot so
|
||||||
// without a lock, so they must be atomic.
|
// a replacement request cannot tear a request already being consumed.
|
||||||
_Atomic(bool) pendingHDRApply;
|
LG_Lock pendingHDRLock;
|
||||||
_Atomic(bool) pendingHDRClear;
|
enum WaylandHDRPendingAction pendingHDRAction;
|
||||||
bool pendingHDRPQ;
|
struct WaylandHDRParameters pendingHDR;
|
||||||
bool pendingHDRMetadata;
|
|
||||||
uint16_t pendingHDRDisplayPrimary[3][2];
|
|
||||||
uint16_t pendingHDRWhitePoint[2];
|
|
||||||
uint32_t pendingHDRMaxDisplayLuminance;
|
|
||||||
uint32_t pendingHDRMinDisplayLuminance;
|
|
||||||
uint32_t pendingHDRMaxCLL;
|
|
||||||
uint32_t pendingHDRMaxFALL;
|
|
||||||
|
|
||||||
LGEvent * frameEvent;
|
LGEvent * frameEvent;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user