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) */