From f2fc45e5f1489b90024b1114f175257aecc9476b Mon Sep 17 00:00:00 2001 From: bjornstahl Date: Sat, 20 May 2023 05:11:49 +0200 Subject: [PATCH] (lua/shmif/egl-dri) wire up hdr metadata This will version bump shmif as some things go from deprecated to removed. The HDR16 metadata _ext substructure gets fleshed out and renamed across all layers. Some minor steps are missing still before durden et al. can get away with tonemapping and full colourspace controls, but this should be the main patch that takes changing interfaces. On the Lua level video_displaymode with the argument format that takes a table can now add keys for controlling the coordinates of targetted display primaries and whitepoint, as well as update the mastering and targetted light levels. Next patch will cover the actual drm toggles for activating the metadata, as well as providing the added information to the frame delivery event so that the WM can decide to update display metadata similarly to how the CM subprotocol works. --- CHANGELOG.md | 4 +++ doc/launch_target.lua | 6 ++--- src/engine/arcan_lua.c | 37 ++++++++++++++++------------ src/platform/posix/frameserver.c | 8 +++--- src/platform/video_platform.h | 17 +++++++++++++ src/shmif/CMakeLists.txt | 2 +- src/shmif/arcan_shmif_control.h | 34 +++++++++----------------- src/shmif/arcan_shmif_interop.h | 2 +- src/shmif/arcan_shmif_sub.h | 42 ++++++++++++++++++++++++++++++-- 9 files changed, 103 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 533db09ab..3c06e6d87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * target_input long messages are now marked as multipart * convey tui/tpack state in resize events * target\_anchorhint added for informing clients about positioning and hierarchy + * video\_displaymode expose eotf / coordinates for primaries and contents light levels ## Core * respect border attribute in text rasteriser @@ -35,10 +36,13 @@ * egl-dri: evict streams * egl-dri: default to atomic over legacy * egl-dri: retain device tracking for unmapped display + * egl-dri: add hdr infoframe metadata to platform ## Shmif * add audio only- segment type * wire up ext venc resize for compressed video passthrough + * extend hdr vsub with more metadata + * dropped unused rhints and rename hdr16f (version bump) ## Decode * defer REGISTER until proto argument has been parsed, let text register as TUI diff --git a/doc/launch_target.lua b/doc/launch_target.lua index 99c6ff0de..3caf635bb 100644 --- a/doc/launch_target.lua +++ b/doc/launch_target.lua @@ -218,9 +218,9 @@ -- "browser", "encoder", "titlebar", "sensor", "service", "bridge-x11", -- "bridge-wayland", "debug", "widget", "audio" -- --- @tblent: "proto_update", {cm, vr, hdrf16, ldr, vobj} - the set of negotiated --- subprotocols has changed, each member is a boolean indicating if the subprotocol --- is available or not. +-- @tblent: "proto_update", {cm, vr, hdr, vobj} - the set of negotiated +-- subprotocols has changed, each member is a boolean indicating if the +-- subprotocol is available or not. -- -- @tblent: "ramp_update", {index} - for clients that have been allowed access to -- the color ramp subprotocol, this event will be triggered for each mapped ramp diff --git a/src/engine/arcan_lua.c b/src/engine/arcan_lua.c index 47e27d351..9ad7f223f 100644 --- a/src/engine/arcan_lua.c +++ b/src/engine/arcan_lua.c @@ -4705,8 +4705,7 @@ bool arcan_lua_pushevent(lua_State* ctx, arcan_event* ev) case EVENT_FSRV_APROTO: tblstr(ctx, "kind", "proto_change", top); tblbool(ctx, "cm", (ev->fsrv.aproto & SHMIF_META_CM) > 0, top); - tblbool(ctx, "hdrf16", (ev->fsrv.aproto & SHMIF_META_HDRF16) > 0, top); - tblbool(ctx, "ldef", (ev->fsrv.aproto & SHMIF_META_LDEF) > 0, top); + tblbool(ctx, "hdr", (ev->fsrv.aproto & SHMIF_META_HDR) > 0, top); tblbool(ctx, "vobj", (ev->fsrv.aproto & SHMIF_META_VOBJ) > 0, top); tblbool(ctx, "vr", (ev->fsrv.aproto & SHMIF_META_VR) > 0, top); break; @@ -6280,6 +6279,20 @@ static int videodisplay(lua_State* ctx) platform_mode_id mode = luaL_checknumber(ctx, 2); opts.vrr = intblfloat(ctx, 3, "vrr"); opts.depth = intblfloat(ctx, 3, "format"); + + if + (opts.depth == VSTORE_HINT_HIDEF || opts.depth == VSTORE_HINT_F16 || + opts.depth == VSTORE_HINT_F32){ + opts.primaries_xy.white[0] = intblfloat(ctx, 3, "whitepoint_x"); + opts.primaries_xy.white[1] = intblfloat(ctx, 3, "whitepoint_y"); + opts.primaries_xy.green[0] = intblfloat(ctx, 3, "primary_green_x"); + opts.primaries_xy.green[1] = intblfloat(ctx, 3, "primary_green_y"); + opts.primaries_xy.red[0] = intblfloat(ctx, 3, "primary_red_x"); + opts.primaries_xy.red[1] = intblfloat(ctx, 3, "primary_red_y"); + opts.primaries_xy.blue[0] = intblfloat(ctx, 3, "primary_blue_x"); + opts.primaries_xy.blue[1] = intblfloat(ctx, 3, "primary_blue_y"); + } + lua_pushboolean(ctx, platform_video_set_mode(id, mode, opts)); } else { @@ -8009,8 +8022,7 @@ enum target_flags { TARGET_FLAG_AUTOCLOCK, TARGET_FLAG_NO_BUFFERPASS, TARGET_FLAG_ALLOW_CM, - TARGET_FLAG_ALLOW_HDRF16, - TARGET_FLAG_ALLOW_LDEF, + TARGET_FLAG_ALLOW_HDR, TARGET_FLAG_ALLOW_VOBJ, TARGET_FLAG_ALLOW_INPUT, TARGET_FLAG_ALLOW_GPUAUTH, @@ -8073,18 +8085,11 @@ static void updateflag(arcan_vobj_id vid, enum target_flags flag, bool toggle) fsrv->metamask &= ~SHMIF_META_CM; break; - case TARGET_FLAG_ALLOW_HDRF16: - if (toggle) - fsrv->metamask |= SHMIF_META_HDRF16; - else - fsrv->metamask &= ~SHMIF_META_HDRF16; - break; - - case TARGET_FLAG_ALLOW_LDEF: + case TARGET_FLAG_ALLOW_HDR: if (toggle) - fsrv->metamask |= SHMIF_META_LDEF; + fsrv->metamask |= SHMIF_META_HDR; else - fsrv->metamask &= ~SHMIF_META_LDEF; + fsrv->metamask &= ~SHMIF_META_HDR; break; case TARGET_FLAG_ALLOW_VOBJ: @@ -12230,8 +12235,8 @@ void arcan_lua_pushglobalconsts(lua_State* ctx){ {"TARGET_AUTOCLOCK", TARGET_FLAG_AUTOCLOCK}, {"TARGET_NOBUFFERPASS", TARGET_FLAG_NO_BUFFERPASS}, {"TARGET_ALLOWCM", TARGET_FLAG_ALLOW_CM}, -{"TARGET_ALLOWHDR", TARGET_FLAG_ALLOW_HDRF16}, -{"TARGET_ALLOWLODEF", TARGET_FLAG_ALLOW_LDEF}, +{"TARGET_ALLOWHDR", TARGET_FLAG_ALLOW_HDR}, +{"TARGET_ALLOWLODEF", 0}, /* deprecated */ {"TARGET_ALLOWVECTOR", TARGET_FLAG_ALLOW_VOBJ}, {"TARGET_ALLOWINPUT", TARGET_FLAG_ALLOW_INPUT}, {"TARGET_ALLOWGPU", TARGET_FLAG_ALLOW_GPUAUTH}, diff --git a/src/platform/posix/frameserver.c b/src/platform/posix/frameserver.c index 83b2b3234..9a88e2aa6 100644 --- a/src/platform/posix/frameserver.c +++ b/src/platform/posix/frameserver.c @@ -816,7 +816,7 @@ static size_t fsrv_protosize(arcan_frameserver* ctx, if (tot % sizeof(max_align_t) != 0) tot += tot - (tot % sizeof(max_align_t)); - if (proto & SHMIF_META_HDRF16){ + if (proto & SHMIF_META_HDR){ /* nothing now, possibly reserved for tone-mapping */ } dofs->ofs_hdr = dofs->sz_hdr = 0; @@ -1224,8 +1224,10 @@ static void fsrv_setproto(arcan_frameserver* ctx, else ctx->desc.aext.gamma = NULL; - if (proto & SHMIF_META_HDRF16){ -/* shouldn't "need" anything here right now */ +/* The hinted metadata comes as per target_displayhint with a reference + * display, that stage checks for hdr metadata, locks and updates. In the other + * direction metadata is transferred on sigvid synch */ + if (proto & SHMIF_META_HDR){ ctx->desc.aext.hdr = (struct arcan_shmif_hdr*)(base + aofs->ofs_hdr); memset(ctx->desc.aext.hdr, '\0', aofs->sz_hdr); } diff --git a/src/platform/video_platform.h b/src/platform/video_platform.h index b488a6d84..58ab0e386 100644 --- a/src/platform/video_platform.h +++ b/src/platform/video_platform.h @@ -195,6 +195,23 @@ bool platform_video_display_edid(platform_display_id did, struct platform_mode_opts { int depth; float vrr; + +/* + * these are just modeled after libdrm/drm_mode.h + */ + bool hdr_meta; + int eotf; + struct { + float white[2]; + float red[2]; + float green[2]; + float blue[2]; + } primaries_xy; + + uint16_t max_disp_luma; + uint16_t min_disp_luma; + uint16_t max_cll; + uint16_t max_fall; }; bool platform_video_set_mode( diff --git a/src/shmif/CMakeLists.txt b/src/shmif/CMakeLists.txt index 62dff7507..c3c791155 100644 --- a/src/shmif/CMakeLists.txt +++ b/src/shmif/CMakeLists.txt @@ -23,7 +23,7 @@ # Installs: (if ARCAN_SOURCE_DIR is not set) # set(ASHMIF_MAJOR 0) -set(ASHMIF_MINOR 15) +set(ASHMIF_MINOR 16) if (ARCAN_SOURCE_DIR) set(ASD ${ARCAN_SOURCE_DIR}) diff --git a/src/shmif/arcan_shmif_control.h b/src/shmif/arcan_shmif_control.h index c8197b403..445bf6836 100644 --- a/src/shmif/arcan_shmif_control.h +++ b/src/shmif/arcan_shmif_control.h @@ -514,11 +514,10 @@ enum shmif_ext_meta { SHMIF_META_CM = 2, /* - * The video buffers will be switched to represent a 16-bit Float( - * R16,G16,B16,A16) format for HDR content and tone-mapping or HDR output - * is expected of the arcan instance. + * The video buffers will be switched to represent uint10, fp16 or fp32 + * format for higher precision SDR and for HDR contents. */ - SHMIF_META_HDRF16 = 4, + SHMIF_META_HDR = 4, /* * This is reserved and not completely fleshed out yet, @@ -536,16 +535,13 @@ enum shmif_ext_meta { SHMIF_META_VR = 16, /* - * Similar to HDR16, but switch to half-size mode (R8G8B8A8 -> RGB565) + * Similar to HDR - but the video buffer is interpreted as a compressed video + * frame. This is primarily to let clients that have a valid h264, av1, ... + * stream forward this without decoding. If the sink detects an unrecoverable + * error in the stream, BUFFER_FAIL will be emitted back. Compressed and raw + * formats can be toggled by setting a valid or empty ({0}) fourcc. */ - SHMIF_META_LDEF = 32, - -/* - * Similar to HDR16, LDEF - but the video buffer is interpreted as a - * compressed video frame. This is primarily to let cliens that have - * a valid h264, av1, ... stream forward this without decoding. - */ - SHMIF_META_VENC = 64 + SHMIF_META_VENC = 32 }; /* @@ -934,6 +930,8 @@ enum rhint_mask { * Setting this flag indicates that the source colorspace is in sRGB format * and that the engine should pick shaders and blending algorithms that can * take this non-linearity into account. + * + * This is ignored if HDR has been negotiated in resize_ext. */ SHMIF_RHINT_CSPACE_SRGB = 8, @@ -955,16 +953,6 @@ enum rhint_mask { */ SHMIF_RHINT_VSIGNAL_EV = 32, -/* - * [Reserved, not yet used] - * Change the buffer contents management method to be a chain of dirty - * rectangles rather than one continous buffer. This means that the contents of - * the normal vidp, stride and pitch members may mutate between calls to - * arcan_shmif_dirty and that it is write only, you can't use it for reliable - * blending etc. Setting this bit will invalidate SHMIF_RHINT_SUBREGION. - */ - SHMIF_RHINT_SUBREGION_CHAIN = 64, - /* * Changes the buffer contents to be packed in the TPACK format (see * tui/raster). This means that the server side will ignore the normal size diff --git a/src/shmif/arcan_shmif_interop.h b/src/shmif/arcan_shmif_interop.h index 0e57cbf40..79f3b42df 100644 --- a/src/shmif/arcan_shmif_interop.h +++ b/src/shmif/arcan_shmif_interop.h @@ -41,7 +41,7 @@ * during _integrity_check */ #define ASHMIF_VERSION_MAJOR 0 -#define ASHMIF_VERSION_MINOR 15 +#define ASHMIF_VERSION_MINOR 16 #ifndef LOG #define LOG(X, ...) (fprintf(stderr, "[%lld]" X, arcan_timemillis(), ## __VA_ARGS__)) diff --git a/src/shmif/arcan_shmif_sub.h b/src/shmif/arcan_shmif_sub.h index 50bd6e4cf..8f17c49f7 100644 --- a/src/shmif/arcan_shmif_sub.h +++ b/src/shmif/arcan_shmif_sub.h @@ -107,8 +107,46 @@ struct arcan_shmif_ofstbl { }; }; -struct arcan_shmif_hdr16f { - int unused; +/* + * Practically speaking these will only be used witin libdrm like settings, + * thus the fields practically match libdrm expected metadata. For other + * applications + */ +struct arcan_shmif_hdr_metadata { + bool valid; + int eotf; + + struct { + float white[2]; + float red[2]; + float green[2]; + float blue[2]; + } primaries; + + uint16_t max_disp_luma; + uint16_t min_disp_luma; + uint16_t max_cll; + uint16_t max_fall; +}; + +/* HDR is something of a misnomer here, it can also refer to SDR contents with + * higher precision (e.g. 10-bit). In that case the SDR eotf mode is specified. + * The values here match what libdrm metadata takes. */ +enum shmif_hdr_eotf { + SHMIF_EOTF_SDR = 0, + SHMIF_EOTF_HDR = 1, + SHMIF_EOTF_ST2084 = 2, + SHMIF_EOTF_HLG = 3 +}; + +struct arcan_shmif_hdr { + int format; /* 0 = fp32 rgba, 1 = fp16 rgba, 2 = 10-bit rgba in 1010102 */ + +/* PRODUCER SET */ + struct arcan_shmif_hdr_metadata source; + +/* CONSUMER SET - updated on DISPLAYHINT, if known / applicable */ + struct arcan_shmif_hdr_metadata sink; }; /* verified during _signal, framesize <= w * h * sizeof(shmif_pixel) */