diff --git a/src/backends/native/meta-onscreen-native.c b/src/backends/native/meta-onscreen-native.c index 81c6857e7..24d7c04a1 100644 --- a/src/backends/native/meta-onscreen-native.c +++ b/src/backends/native/meta-onscreen-native.c @@ -445,32 +445,30 @@ static MetaKmsPlaneAssignment * assign_primary_plane (MetaCrtcKms *crtc_kms, MetaDrmBuffer *buffer, MetaKmsUpdate *kms_update, - MetaKmsAssignPlaneFlag flags) + MetaKmsAssignPlaneFlag flags, + const graphene_rect_t *src_rect, + const MtkRectangle *dst_rect) { MetaCrtc *crtc = META_CRTC (crtc_kms); - const MetaCrtcConfig *crtc_config; - const MetaCrtcModeInfo *crtc_mode_info; - MetaFixed16Rectangle src_rect; - MtkRectangle dst_rect; + MetaFixed16Rectangle src_rect_fixed16; MetaKmsCrtc *kms_crtc; MetaKmsPlane *primary_kms_plane; MetaKmsPlaneAssignment *plane_assignment; - crtc_config = meta_crtc_get_config (crtc); - crtc_mode_info = meta_crtc_mode_get_info (crtc_config->mode); + src_rect_fixed16 = (MetaFixed16Rectangle) { + .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) { - .x = meta_fixed_16_from_int (0), - .y = meta_fixed_16_from_int (0), - .width = meta_fixed_16_from_int (crtc_mode_info->width), - .height = meta_fixed_16_from_int (crtc_mode_info->height), - }; - dst_rect = (MtkRectangle) { - .x = 0, - .y = 0, - .width = crtc_mode_info->width, - .height = crtc_mode_info->height, - }; + meta_topic (META_DEBUG_KMS, + "Assigning buffer to primary plane update on CRTC " + "(%" G_GUINT64_FORMAT ") with src rect %f,%f %fx%f " + "and dst rect %d,%d %dx%d", + meta_crtc_get_id (crtc), src_rect->origin.x, src_rect->origin.y, + src_rect->size.width, src_rect->size.height, + dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height); kms_crtc = meta_crtc_kms_get_kms_crtc (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, primary_kms_plane, buffer, - src_rect, - dst_rect, + src_rect_fixed16, + *dst_rect, flags); 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) { case META_RENDERER_NATIVE_MODE_GBM: + graphene_rect_t src_rect; + MtkRectangle dst_rect; + 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, buffer, kms_update, - flags); + flags, + &src_rect, + &dst_rect); 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: { MetaDrmBuffer *buffer; + graphene_rect_t src_rect; + MtkRectangle dst_rect; 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; } #endif @@ -1445,15 +1492,25 @@ meta_onscreen_native_is_buffer_scanout_compatible (CoglOnscreen *onscreen, MetaDrmBuffer *buffer; g_autoptr (MetaKmsFeedback) kms_feedback = NULL; MetaKmsFeedbackResult result; + graphene_rect_t src_rect; + MtkRectangle dst_rect; gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); kms_device = meta_gpu_kms_get_kms_device (gpu_kms); kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); 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)); - assign_primary_plane (crtc_kms, buffer, test_update, - META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT); + assign_primary_plane (crtc_kms, + buffer, + test_update, + META_KMS_ASSIGN_PLANE_FLAG_DIRECT_SCANOUT, + &src_rect, + &dst_rect); meta_topic (META_DEBUG_KMS, "Posting direct scanout test update for CRTC %u (%s) synchronously", diff --git a/src/wayland/meta-wayland-buffer.c b/src/wayland/meta-wayland-buffer.c index f02abc898..a2ddcf567 100644 --- a/src/wayland/meta-wayland-buffer.c +++ b/src/wayland/meta-wayland-buffer.c @@ -909,8 +909,10 @@ scanout_destroyed (gpointer data, } CoglScanout * -meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer, - CoglOnscreen *onscreen) +meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer, + CoglOnscreen *onscreen, + const graphene_rect_t *src_rect, + const MtkRectangle *dst_rect) { CoglScanout *scanout = NULL; @@ -935,11 +937,20 @@ meta_wayland_buffer_try_acquire_scanout (MetaWaylandBuffer *buffer, "Buffer type not scanout compatible"); return NULL; 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); break; 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; } case META_WAYLAND_BUFFER_TYPE_UNKNOWN: diff --git a/src/wayland/meta-wayland-buffer.h b/src/wayland/meta-wayland-buffer.h index 70a58d622..23aea7cb2 100644 --- a/src/wayland/meta-wayland-buffer.h +++ b/src/wayland/meta-wayland-buffer.h @@ -101,6 +101,8 @@ void meta_wayland_buffer_process_damage (MetaWaylandBuff MetaMultiTexture *texture, MtkRegion *region); 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); diff --git a/src/wayland/meta-wayland-dma-buf.c b/src/wayland/meta-wayland-dma-buf.c index 3f0447dd7..7085bec31 100644 --- a/src/wayland/meta-wayland-dma-buf.c +++ b/src/wayland/meta-wayland-dma-buf.c @@ -605,8 +605,10 @@ import_scanout_gbm_bo (MetaWaylandDmaBufBuffer *dma_buf, #endif CoglScanout * -meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer, - CoglOnscreen *onscreen) +meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer, + CoglOnscreen *onscreen, + const graphene_rect_t *src_rect, + const MtkRectangle *dst_rect) { #ifdef HAVE_NATIVE_BACKEND 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))); + 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)) { meta_topic (META_DEBUG_RENDER, diff --git a/src/wayland/meta-wayland-dma-buf.h b/src/wayland/meta-wayland-dma-buf.h index 026e4837d..8f71dac42 100644 --- a/src/wayland/meta-wayland-dma-buf.h +++ b/src/wayland/meta-wayland-dma-buf.h @@ -64,5 +64,7 @@ meta_wayland_dma_buf_create_source (MetaWaylandBuffer *buffer, gpointer user_data); CoglScanout * -meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer, - CoglOnscreen *onscreen); +meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandBuffer *buffer, + CoglOnscreen *onscreen, + const graphene_rect_t *src_rect, + const MtkRectangle *dst_rect); diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 213bccd64..ec5ac403f 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -2264,7 +2264,9 @@ meta_wayland_surface_try_acquire_scanout (MetaWaylandSurface *surface, return NULL; return meta_wayland_buffer_try_acquire_scanout (surface->buffer, - onscreen); + onscreen, + NULL, + NULL); } MetaCrtc *