crtc/kms: Pass on src and dst rects to primary plane assignments

This allows us to pass on the related data from CoglScanouts.

If dst_rect does not match the mode, we assume that not covered areas
are opaque black - usually black bars around a centered surface.

While such driver behaviour does not appear to be documented (well) yet,
it seems to be followed by all known existing drivers and is used in a
similar way in ChromeOS.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3177>
This commit is contained in:
Robert Mader 2023-08-14 13:00:15 +02:00 committed by Marge Bot
parent 26ce5cd6be
commit adc776d0d7
6 changed files with 114 additions and 35 deletions

View File

@ -445,32 +445,30 @@ static MetaKmsPlaneAssignment *
assign_primary_plane (MetaCrtcKms *crtc_kms, assign_primary_plane (MetaCrtcKms *crtc_kms,
MetaDrmBuffer *buffer, MetaDrmBuffer *buffer,
MetaKmsUpdate *kms_update, MetaKmsUpdate *kms_update,
MetaKmsAssignPlaneFlag flags) MetaKmsAssignPlaneFlag flags,
const graphene_rect_t *src_rect,
const MtkRectangle *dst_rect)
{ {
MetaCrtc *crtc = META_CRTC (crtc_kms); MetaCrtc *crtc = META_CRTC (crtc_kms);
const MetaCrtcConfig *crtc_config; MetaFixed16Rectangle src_rect_fixed16;
const MetaCrtcModeInfo *crtc_mode_info;
MetaFixed16Rectangle src_rect;
MtkRectangle dst_rect;
MetaKmsCrtc *kms_crtc; MetaKmsCrtc *kms_crtc;
MetaKmsPlane *primary_kms_plane; MetaKmsPlane *primary_kms_plane;
MetaKmsPlaneAssignment *plane_assignment; MetaKmsPlaneAssignment *plane_assignment;
crtc_config = meta_crtc_get_config (crtc); src_rect_fixed16 = (MetaFixed16Rectangle) {
crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode); .x = meta_fixed_16_from_double (src_rect->origin.x),
.y = meta_fixed_16_from_double (src_rect->origin.y),
.width = meta_fixed_16_from_double (src_rect->size.width),
.height = meta_fixed_16_from_double (src_rect->size.height),
};
src_rect = (MetaFixed16Rectangle) { meta_topic (META_DEBUG_KMS,
.x = meta_fixed_16_from_int (0), "Assigning buffer to primary plane update on CRTC "
.y = meta_fixed_16_from_int (0), "(%" G_GUINT64_FORMAT ") with src rect %f,%f %fx%f "
.width = meta_fixed_16_from_int (crtc_mode_info->width), "and dst rect %d,%d %dx%d",
.height = meta_fixed_16_from_int (crtc_mode_info->height), meta_crtc_get_id (crtc), src_rect->origin.x, src_rect->origin.y,
}; src_rect->size.width, src_rect->size.height,
dst_rect = (MtkRectangle) { dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height);
.x = 0,
.y = 0,
.width = crtc_mode_info->width,
.height = crtc_mode_info->height,
};
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
primary_kms_plane = meta_crtc_kms_get_assigned_primary_plane (crtc_kms); primary_kms_plane = meta_crtc_kms_get_assigned_primary_plane (crtc_kms);
@ -478,8 +476,8 @@ assign_primary_plane (MetaCrtcKms *crtc_kms,
kms_crtc, kms_crtc,
primary_kms_plane, primary_kms_plane,
buffer, buffer,
src_rect, src_rect_fixed16,
dst_rect, *dst_rect,
flags); flags);
apply_transform (crtc_kms, plane_assignment, primary_kms_plane); apply_transform (crtc_kms, plane_assignment, primary_kms_plane);
@ -517,12 +515,40 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
switch (renderer_gpu_data->mode) switch (renderer_gpu_data->mode)
{ {
case META_RENDERER_NATIVE_MODE_GBM: case META_RENDERER_NATIVE_MODE_GBM:
graphene_rect_t src_rect;
MtkRectangle dst_rect;
buffer = onscreen_native->gbm.next_fb; buffer = onscreen_native->gbm.next_fb;
if (onscreen_native->gbm.next_scanout)
{
cogl_scanout_get_src_rect (onscreen_native->gbm.next_scanout,
&src_rect);
cogl_scanout_get_dst_rect (onscreen_native->gbm.next_scanout,
&dst_rect);
}
else
{
src_rect = (graphene_rect_t) {
.origin.x = 0,
.origin.y = 0,
.size.width = meta_drm_buffer_get_width (buffer),
.size.height = meta_drm_buffer_get_height (buffer)
};
dst_rect = (MtkRectangle) {
.x = 0,
.y = 0,
.width = meta_drm_buffer_get_width (buffer),
.height = meta_drm_buffer_get_height (buffer)
};
}
plane_assignment = assign_primary_plane (crtc_kms, plane_assignment = assign_primary_plane (crtc_kms,
buffer, buffer,
kms_update, kms_update,
flags); flags,
&src_rect,
&dst_rect);
if (rectangles != NULL && n_rectangles != 0) if (rectangles != NULL && n_rectangles != 0)
{ {
@ -669,10 +695,31 @@ meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen,
case META_RENDERER_NATIVE_MODE_EGL_DEVICE: case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
{ {
MetaDrmBuffer *buffer; MetaDrmBuffer *buffer;
graphene_rect_t src_rect;
MtkRectangle dst_rect;
buffer = META_DRM_BUFFER (onscreen_native->egl.dumb_fb); buffer = META_DRM_BUFFER (onscreen_native->egl.dumb_fb);
assign_primary_plane (crtc_kms, buffer, kms_update,
META_KMS_ASSIGN_PLANE_FLAG_NONE); src_rect = (graphene_rect_t) {
.origin.x = 0,
.origin.y = 0,
.size.width = meta_drm_buffer_get_width (buffer),
.size.height = meta_drm_buffer_get_height (buffer)
};
dst_rect = (MtkRectangle) {
.x = 0,
.y = 0,
.width = meta_drm_buffer_get_width (buffer),
.height = meta_drm_buffer_get_height (buffer)
};
assign_primary_plane (crtc_kms,
buffer,
kms_update,
META_KMS_ASSIGN_PLANE_FLAG_NONE,
&src_rect,
&dst_rect);
break; break;
} }
#endif #endif
@ -1445,15 +1492,25 @@ meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen,
MetaDrmBuffer *buffer; MetaDrmBuffer *buffer;
g_autoptr (MetaKmsFeedback) kms_feedback = NULL; g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
MetaKmsFeedbackResult result; MetaKmsFeedbackResult result;
graphene_rect_t src_rect;
MtkRectangle dst_rect;
gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc));
kms_device = meta_gpu_kms_get_kms_device (gpu_kms); kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
test_update = meta_kms_update_new (kms_device); test_update = meta_kms_update_new (kms_device);
cogl_scanout_get_src_rect (scanout, &src_rect);
cogl_scanout_get_dst_rect (scanout, &dst_rect);
buffer = META_DRM_BUFFER (cogl_scanout_get_buffer (scanout)); buffer = META_DRM_BUFFER (cogl_scanout_get_buffer (scanout));
assign_primary_plane (crtc_kms, buffer, test_update, assign_primary_plane (crtc_kms,
META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT); buffer,
test_update,
META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT,
&src_rect,
&dst_rect);
meta_topic (META_DEBUG_KMS, meta_topic (META_DEBUG_KMS,
"Posting direct scanout test update for CRTC %u (%s) synchronously", "Posting direct scanout test update for CRTC %u (%s) synchronously",

View File

@ -910,7 +910,9 @@ scanout_destroyed (gpointer data,
CoglScanout * CoglScanout *
meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer, meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer,
CoglOnscreen *onscreen) CoglOnscreen *onscreen,
const graphene_rect_t *src_rect,
const MtkRectangle *dst_rect)
{ {
CoglScanout *scanout = NULL; CoglScanout *scanout = NULL;
@ -935,11 +937,20 @@ meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer,
"Buffer type not scanout compatible"); "Buffer type not scanout compatible");
return NULL; return NULL;
case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE: case META_WAYLAND_BUFFER_TYPE_EGL_IMAGE:
if (src_rect || dst_rect)
{
meta_topic (META_DEBUG_RENDER,
"Buffer type does not support scaling operations");
return NULL;
}
scanout = try_acquire_egl_image_scanout (buffer, onscreen); scanout = try_acquire_egl_image_scanout (buffer, onscreen);
break; break;
case META_WAYLAND_BUFFER_TYPE_DMA_BUF: case META_WAYLAND_BUFFER_TYPE_DMA_BUF:
{ {
scanout = meta_wayland_dma_buf_try_acquire_scanout (buffer, onscreen); scanout = meta_wayland_dma_buf_try_acquire_scanout (buffer,
onscreen,
src_rect,
dst_rect);
break; break;
} }
case META_WAYLAND_BUFFER_TYPE_UNKNOWN: case META_WAYLAND_BUFFER_TYPE_UNKNOWN:

View File

@ -101,6 +101,8 @@ void meta_wayland_buffer_process_damage (MetaWaylandBuff
MetaMultiTexture *texture, MetaMultiTexture *texture,
MtkRegion *region); MtkRegion *region);
CoglScanout * meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer, CoglScanout * meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer,
CoglOnscreen *onscreen); CoglOnscreen *onscreen,
const graphene_rect_t *src_rect,
const MtkRectangle *dst_rect);
void meta_wayland_init_shm (MetaWaylandCompositor *compositor); void meta_wayland_init_shm (MetaWaylandCompositor *compositor);

View File

@ -606,7 +606,9 @@ import_scanout_gbm_bo (MetaWaylandDmaBufBuffer *dma_buf,
CoglScanout * CoglScanout *
meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer, meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer,
CoglOnscreen *onscreen) CoglOnscreen *onscreen,
const graphene_rect_t *src_rect,
const MtkRectangle *dst_rect)
{ {
#ifdef HAVE_NATIVE_BACKEND #ifdef HAVE_NATIVE_BACKEND
MetaWaylandDmaBufBuffer *dma_buf; MetaWaylandDmaBufBuffer *dma_buf;
@ -664,6 +666,9 @@ meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer,
} }
scanout = cogl_scanout_new (COGL_SCANOUT_BUFFER (g_steal_pointer (&fb))); scanout = cogl_scanout_new (COGL_SCANOUT_BUFFER (g_steal_pointer (&fb)));
cogl_scanout_set_src_rect (scanout, src_rect);
cogl_scanout_set_dst_rect (scanout, dst_rect);
if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen, scanout)) if (!meta_onscreen_native_is_buffer_scanout_compatible (onscreen, scanout))
{ {
meta_topic (META_DEBUG_RENDER, meta_topic (META_DEBUG_RENDER,

View File

@ -65,4 +65,6 @@ meta_wayland_dma_buf_create_source (MetaWaylandBuffer *buffer,
CoglScanout * CoglScanout *
meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer, meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer,
CoglOnscreen *onscreen); CoglOnscreen *onscreen,
const graphene_rect_t *src_rect,
const MtkRectangle *dst_rect);

View File

@ -2264,7 +2264,9 @@ meta_wayland_surface_try_acquire_scanout (MetaWaylandSurface *surface,
return NULL; return NULL;
return meta_wayland_buffer_try_acquire_scanout (surface->buffer, return meta_wayland_buffer_try_acquire_scanout (surface->buffer,
onscreen); onscreen,
NULL,
NULL);
} }
MetaCrtc * MetaCrtc *