aboutsummaryrefslogtreecommitdiff
path: root/kms/server/kms_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'kms/server/kms_server.c')
-rw-r--r--kms/server/kms_server.c68
1 files changed, 47 insertions, 21 deletions
diff --git a/kms/server/kms_server.c b/kms/server/kms_server.c
index 6062074..8bc5d8c 100644
--- a/kms/server/kms_server.c
+++ b/kms/server/kms_server.c
@@ -25,6 +25,7 @@ typedef struct {
typedef struct {
uint32_t connector_id;
uint64_t crtc_id;
+ uint64_t hdr_metadata_blob_id;
} connector_crtc_pair;
typedef struct {
@@ -188,12 +189,12 @@ static uint32_t plane_get_properties(int drmfd, uint32_t plane_id, bool *is_curs
}
/* Returns 0 if not found */
-static uint32_t get_connector_by_crtc_id(const connector_to_crtc_map *c2crtc_map, uint32_t crtc_id) {
+static const connector_crtc_pair* get_connector_pair_by_crtc_id(const connector_to_crtc_map *c2crtc_map, uint32_t crtc_id) {
for(int i = 0; i < c2crtc_map->num_maps; ++i) {
if(c2crtc_map->maps[i].crtc_id == crtc_id)
- return c2crtc_map->maps[i].connector_id;
+ return &c2crtc_map->maps[i];
}
- return 0;
+ return NULL;
}
static void map_crtc_to_connector_ids(gsr_drm *drm, connector_to_crtc_map *c2crtc_map) {
@@ -210,8 +211,12 @@ static void map_crtc_to_connector_ids(gsr_drm *drm, connector_to_crtc_map *c2crt
uint64_t crtc_id = 0;
connector_get_property_by_name(drm->drmfd, connector, "CRTC_ID", &crtc_id);
+ uint64_t hdr_output_metadata_blob_id = 0;
+ connector_get_property_by_name(drm->drmfd, connector, "HDR_OUTPUT_METADATA", &hdr_output_metadata_blob_id);
+
c2crtc_map->maps[c2crtc_map->num_maps].connector_id = connector->connector_id;
c2crtc_map->maps[c2crtc_map->num_maps].crtc_id = crtc_id;
+ c2crtc_map->maps[c2crtc_map->num_maps].hdr_metadata_blob_id = hdr_output_metadata_blob_id;
++c2crtc_map->num_maps;
drmModeFreeConnector(connector);
@@ -239,6 +244,18 @@ static void drm_mode_cleanup_handles(int drmfd, drmModeFB2Ptr drmfb) {
}
}
+static bool get_hdr_metadata(int drm_fd, uint64_t hdr_metadata_blob_id, struct hdr_output_metadata *hdr_metadata) {
+ drmModePropertyBlobPtr hdr_metadata_blob = drmModeGetPropertyBlob(drm_fd, hdr_metadata_blob_id);
+ if(!hdr_metadata_blob)
+ return false;
+
+ if(hdr_metadata_blob->length >= sizeof(struct hdr_output_metadata))
+ *hdr_metadata = *(struct hdr_output_metadata*)hdr_metadata_blob->data;
+
+ drmModeFreePropertyBlob(hdr_metadata_blob);
+ return true;
+}
+
static int kms_get_fb(gsr_drm *drm, gsr_kms_response *response, connector_to_crtc_map *c2crtc_map) {
int result = -1;
@@ -289,30 +306,39 @@ static int kms_get_fb(gsr_drm *drm, gsr_kms_response *response, connector_to_crt
goto cleanup_handles;
}
+ const int fd_index = response->num_fds;
+
bool is_cursor = false;
int x = 0, y = 0, src_x = 0, src_y = 0, src_w = 0, src_h = 0;
plane_get_properties(drm->drmfd, plane->plane_id, &is_cursor, &x, &y, &src_x, &src_y, &src_w, &src_h);
- response->fds[response->num_fds].fd = fb_fd;
- response->fds[response->num_fds].width = drmfb->width;
- response->fds[response->num_fds].height = drmfb->height;
- response->fds[response->num_fds].pitch = drmfb->pitches[0];
- response->fds[response->num_fds].offset = drmfb->offsets[0];
- response->fds[response->num_fds].pixel_format = drmfb->pixel_format;
- response->fds[response->num_fds].modifier = drmfb->modifier;
- response->fds[response->num_fds].connector_id = get_connector_by_crtc_id(c2crtc_map, plane->crtc_id);
- response->fds[response->num_fds].is_cursor = is_cursor;
- response->fds[response->num_fds].is_combined_plane = false;
+ const connector_crtc_pair *crtc_pair = get_connector_pair_by_crtc_id(c2crtc_map, plane->crtc_id);
+ if(crtc_pair && crtc_pair->hdr_metadata_blob_id) {
+ response->fds[fd_index].has_hdr_metadata = get_hdr_metadata(drm->drmfd, crtc_pair->hdr_metadata_blob_id, &response->fds[fd_index].hdr_metadata);
+ } else {
+ response->fds[fd_index].has_hdr_metadata = false;
+ }
+
+ response->fds[fd_index].fd = fb_fd;
+ response->fds[fd_index].width = drmfb->width;
+ response->fds[fd_index].height = drmfb->height;
+ response->fds[fd_index].pitch = drmfb->pitches[0];
+ response->fds[fd_index].offset = drmfb->offsets[0];
+ response->fds[fd_index].pixel_format = drmfb->pixel_format;
+ response->fds[fd_index].modifier = drmfb->modifier;
+ response->fds[fd_index].connector_id = crtc_pair ? crtc_pair->connector_id : 0;
+ response->fds[fd_index].is_cursor = is_cursor;
+ response->fds[fd_index].is_combined_plane = false;
if(is_cursor) {
- response->fds[response->num_fds].x = x;
- response->fds[response->num_fds].y = y;
- response->fds[response->num_fds].src_w = 0;
- response->fds[response->num_fds].src_h = 0;
+ response->fds[fd_index].x = x;
+ response->fds[fd_index].y = y;
+ response->fds[fd_index].src_w = 0;
+ response->fds[fd_index].src_h = 0;
} else {
- response->fds[response->num_fds].x = src_x;
- response->fds[response->num_fds].y = src_y;
- response->fds[response->num_fds].src_w = src_w;
- response->fds[response->num_fds].src_h = src_h;
+ response->fds[fd_index].x = src_x;
+ response->fds[fd_index].y = src_y;
+ response->fds[fd_index].src_w = src_w;
+ response->fds[fd_index].src_h = src_h;
}
++response->num_fds;