diff options
Diffstat (limited to 'kms/server')
-rw-r--r-- | kms/server/kms_server.c | 91 |
1 files changed, 59 insertions, 32 deletions
diff --git a/kms/server/kms_server.c b/kms/server/kms_server.c index 070875b..88d4b73 100644 --- a/kms/server/kms_server.c +++ b/kms/server/kms_server.c @@ -145,12 +145,13 @@ typedef enum { PLANE_PROPERTY_SRC_H = 1 << 5, PLANE_PROPERTY_IS_CURSOR = 1 << 6, PLANE_PROPERTY_IS_PRIMARY = 1 << 7, + PLANE_PROPERTY_IS_OVERLAY = 1 << 8, } plane_property_mask; /* Returns plane_property_mask */ -static uint32_t plane_get_properties(int drmfd, uint32_t plane_id, int *x, int *y, int *src_x, int *src_y, int *src_w, int *src_h) { - *x = 0; - *y = 0; +static uint32_t plane_get_properties(int drmfd, uint32_t plane_id, int *crtc_x, int *crtc_y, int *src_x, int *src_y, int *src_w, int *src_h) { + *crtc_x = 0; + *crtc_y = 0; *src_x = 0; *src_y = 0; *src_w = 0; @@ -171,10 +172,10 @@ static uint32_t plane_get_properties(int drmfd, uint32_t plane_id, int *x, int * // SRC_* values are fixed 16.16 points const uint32_t type = prop->flags & (DRM_MODE_PROP_LEGACY_TYPE | DRM_MODE_PROP_EXTENDED_TYPE); if((type & DRM_MODE_PROP_SIGNED_RANGE) && strcmp(prop->name, "CRTC_X") == 0) { - *x = (int)props->prop_values[i]; + *crtc_x = (int)props->prop_values[i]; property_mask |= PLANE_PROPERTY_X; } else if((type & DRM_MODE_PROP_SIGNED_RANGE) && strcmp(prop->name, "CRTC_Y") == 0) { - *y = (int)props->prop_values[i]; + *crtc_y = (int)props->prop_values[i]; property_mask |= PLANE_PROPERTY_Y; } else if((type & DRM_MODE_PROP_RANGE) && strcmp(prop->name, "SRC_X") == 0) { *src_x = (int)(props->prop_values[i] >> 16); @@ -197,6 +198,9 @@ static uint32_t plane_get_properties(int drmfd, uint32_t plane_id, int *x, int * } else if(prop->enums[j].value == current_enum_value && strcmp(prop->enums[j].name, "Cursor") == 0) { property_mask |= PLANE_PROPERTY_IS_CURSOR; break; + } else if(prop->enums[j].value == current_enum_value && strcmp(prop->enums[j].name, "Overlay") == 0) { + property_mask |= PLANE_PROPERTY_IS_OVERLAY; + break; } } } @@ -289,6 +293,16 @@ static int drm_prime_handles_to_fds(gsr_drm *drm, drmModeFB2Ptr drmfb, int *fb_f return GSR_KMS_MAX_DMA_BUFS; } +static int plane_property_get_plane_type(plane_property_mask property_mask) { + if(property_mask & PLANE_PROPERTY_IS_PRIMARY) + return KMS_PLANE_TYPE_PRIMARY; + else if(property_mask & PLANE_PROPERTY_IS_CURSOR) + return KMS_PLANE_TYPE_CURSOR; + else if(property_mask & PLANE_PROPERTY_IS_OVERLAY) + return KMS_PLANE_TYPE_OVERLAY; + return -1; +} + static int kms_get_fb(gsr_drm *drm, gsr_kms_response *response) { int result = -1; @@ -340,9 +354,10 @@ static int kms_get_fb(gsr_drm *drm, gsr_kms_response *response) { // TODO: Check if dimensions have changed by comparing width and height to previous time this was called. // TODO: Support other plane formats than rgb (with multiple planes, such as direct YUV420 on wayland). - int x = 0, y = 0, src_x = 0, src_y = 0, src_w = 0, src_h = 0; - plane_property_mask property_mask = plane_get_properties(drm->drmfd, plane->plane_id, &x, &y, &src_x, &src_y, &src_w, &src_h); - if(!(property_mask & PLANE_PROPERTY_IS_PRIMARY) && !(property_mask & PLANE_PROPERTY_IS_CURSOR)) + int crtc_x = 0, crtc_y = 0, src_x = 0, src_y = 0, src_w = 0, src_h = 0; + const plane_property_mask property_mask = plane_get_properties(drm->drmfd, plane->plane_id, &crtc_x, &crtc_y, &src_x, &src_y, &src_w, &src_h); + const int plane_type = plane_property_get_plane_type(property_mask); + if(plane_type == -1) continue; int fb_fds[GSR_KMS_MAX_DMA_BUFS]; @@ -354,38 +369,50 @@ static int kms_get_fb(gsr_drm *drm, gsr_kms_response *response) { goto cleanup_handles; } - const int item_index = response->num_items; + gsr_kms_response_item *response_item = &response->items[response->num_items]; 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->items[item_index].has_hdr_metadata = get_hdr_metadata(drm->drmfd, crtc_pair->hdr_metadata_blob_id, &response->items[item_index].hdr_metadata); + response_item->has_hdr_metadata = get_hdr_metadata(drm->drmfd, crtc_pair->hdr_metadata_blob_id, &response_item->hdr_metadata); } else { - response->items[item_index].has_hdr_metadata = false; + response_item->has_hdr_metadata = false; } for(int j = 0; j < num_fb_fds; ++j) { - response->items[item_index].dma_buf[j].fd = fb_fds[j]; - response->items[item_index].dma_buf[j].pitch = drmfb->pitches[j]; - response->items[item_index].dma_buf[j].offset = drmfb->offsets[j]; + response_item->dma_buf[j].fd = fb_fds[j]; + response_item->dma_buf[j].pitch = drmfb->pitches[j]; + response_item->dma_buf[j].offset = drmfb->offsets[j]; } - response->items[item_index].num_dma_bufs = num_fb_fds; - - response->items[item_index].width = drmfb->width; - response->items[item_index].height = drmfb->height; - response->items[item_index].pixel_format = drmfb->pixel_format; - response->items[item_index].modifier = drmfb->flags & DRM_MODE_FB_MODIFIERS ? drmfb->modifier : DRM_FORMAT_MOD_INVALID; - response->items[item_index].connector_id = crtc_pair ? crtc_pair->connector_id : 0; - response->items[item_index].is_cursor = property_mask & PLANE_PROPERTY_IS_CURSOR; - if(property_mask & PLANE_PROPERTY_IS_CURSOR) { - response->items[item_index].x = x; - response->items[item_index].y = y; - response->items[item_index].src_w = 0; - response->items[item_index].src_h = 0; - } else { - response->items[item_index].x = src_x; - response->items[item_index].y = src_y; - response->items[item_index].src_w = src_w; - response->items[item_index].src_h = src_h; + response_item->num_dma_bufs = num_fb_fds; + + response_item->width = drmfb->width; + response_item->height = drmfb->height; + response_item->pixel_format = drmfb->pixel_format; + response_item->modifier = drmfb->flags & DRM_MODE_FB_MODIFIERS ? drmfb->modifier : DRM_FORMAT_MOD_INVALID; + response_item->connector_id = crtc_pair ? crtc_pair->connector_id : 0; + response_item->plane_type = plane_type; + switch(response_item->plane_type) { + case KMS_PLANE_TYPE_PRIMARY: { + response_item->x = src_x; + response_item->y = src_y; + response_item->src_w = src_w; + response_item->src_h = src_h; + break; + } + case KMS_PLANE_TYPE_CURSOR: { + response_item->x = crtc_x; + response_item->y = crtc_y; + response_item->src_w = 0; + response_item->src_h = 0; + break; + } + case KMS_PLANE_TYPE_OVERLAY: { + response_item->x = crtc_x; + response_item->y = crtc_y; + response_item->src_w = src_w; + response_item->src_h = src_y; + break; + } } ++response->num_items; |