Skip to content

Commit

Permalink
(lua/shmif/egl-dri) wire up hdr metadata
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
letoram committed May 22, 2023
1 parent fd6f24d commit f2fc45e
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 49 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions doc/launch_target.lua
Expand Up @@ -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
Expand Down
37 changes: 21 additions & 16 deletions src/engine/arcan_lua.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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},
Expand Down
8 changes: 5 additions & 3 deletions src/platform/posix/frameserver.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
17 changes: 17 additions & 0 deletions src/platform/video_platform.h
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion src/shmif/CMakeLists.txt
Expand Up @@ -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})
Expand Down
34 changes: 11 additions & 23 deletions src/shmif/arcan_shmif_control.h
Expand Up @@ -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,
Expand All @@ -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
};

/*
Expand Down Expand Up @@ -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,

Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/shmif/arcan_shmif_interop.h
Expand Up @@ -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__))
Expand Down
42 changes: 40 additions & 2 deletions src/shmif/arcan_shmif_sub.h
Expand Up @@ -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) */
Expand Down

0 comments on commit f2fc45e

Please sign in to comment.