diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c index bad9f72e9..81ebce901 100644 --- a/src/backends/native/meta-crtc-kms.c +++ b/src/backends/native/meta-crtc-kms.c @@ -51,7 +51,8 @@ struct _MetaCrtcKms MetaKmsCrtc *kms_crtc; - MetaKmsPlane *primary_plane; + MetaKmsPlane *assigned_primary_plane; + MetaKmsPlane *assigned_cursor_plane; }; static GQuark kms_crtc_crtc_kms_quark; @@ -205,14 +206,132 @@ meta_crtc_kms_set_gamma_lut (MetaCrtc *crtc, clutter_stage_schedule_update (CLUTTER_STAGE (stage)); } +typedef struct _CrtcKmsAssignment +{ + MetaKmsPlane *primary_plane; + MetaKmsPlane *cursor_plane; +} CrtcKmsAssignment; + +static gboolean +is_plane_assigned (MetaKmsPlane *plane, + MetaKmsPlaneType plane_type, + GPtrArray *crtc_assignments) +{ + size_t i; + + for (i = 0; i < crtc_assignments->len; i++) + { + MetaCrtcAssignment *assigned_crtc_assignment = + g_ptr_array_index (crtc_assignments, i); + CrtcKmsAssignment *kms_assignment; + + if (!META_IS_CRTC_KMS (assigned_crtc_assignment->crtc)) + continue; + + kms_assignment = assigned_crtc_assignment->backend_private; + switch (plane_type) + { + case META_KMS_PLANE_TYPE_PRIMARY: + if (kms_assignment->primary_plane == plane) + return TRUE; + break; + case META_KMS_PLANE_TYPE_CURSOR: + if (kms_assignment->cursor_plane == plane) + return TRUE; + break; + case META_KMS_PLANE_TYPE_OVERLAY: + g_assert_not_reached (); + } + } + + return FALSE; +} + +static MetaKmsPlane * +find_unassigned_plane (MetaCrtcKms *crtc_kms, + MetaKmsPlaneType kms_plane_type, + GPtrArray *crtc_assignments) +{ + MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); + MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc); + GList *l; + + for (l = meta_kms_device_get_planes (kms_device); l; l = l->next) + { + MetaKmsPlane *kms_plane = l->data; + + if (meta_kms_plane_get_plane_type (kms_plane) != kms_plane_type) + continue; + + if (!meta_kms_plane_is_usable_with (kms_plane, kms_crtc)) + continue; + + if (is_plane_assigned (kms_plane, kms_plane_type, + crtc_assignments)) + continue; + + return kms_plane; + } + + return NULL; +} + +static gboolean +meta_crtc_kms_assign_extra (MetaCrtc *crtc, + MetaCrtcAssignment *crtc_assignment, + GPtrArray *crtc_assignments, + GError **error) +{ + MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc); + MetaKmsPlane *primary_plane; + MetaKmsPlane *cursor_plane; + CrtcKmsAssignment *kms_assignment; + + primary_plane = find_unassigned_plane (crtc_kms, META_KMS_PLANE_TYPE_PRIMARY, + crtc_assignments); + if (!primary_plane) + { + MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); + MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc); + + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "No available primary plane found for CRTC %u (%s)", + meta_kms_crtc_get_id (kms_crtc), + meta_kms_device_get_path (kms_device)); + return FALSE; + } + + cursor_plane = find_unassigned_plane (crtc_kms, META_KMS_PLANE_TYPE_CURSOR, + crtc_assignments); + + kms_assignment = g_new0 (CrtcKmsAssignment, 1); + kms_assignment->primary_plane = primary_plane; + kms_assignment->cursor_plane = cursor_plane; + + crtc_assignment->backend_private = kms_assignment; + crtc_assignment->backend_private_destroy = g_free; + + return TRUE; +} + +static void +meta_crtc_kms_set_config (MetaCrtc *crtc, + const MetaCrtcConfig *config, + gpointer backend_private) +{ + MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc); + CrtcKmsAssignment *kms_assignment = backend_private; + + crtc_kms->assigned_primary_plane = kms_assignment->primary_plane; + crtc_kms->assigned_cursor_plane = kms_assignment->cursor_plane; +} + static gboolean is_transform_handled (MetaCrtcKms *crtc_kms, MetaMonitorTransform transform) { - if (!crtc_kms->primary_plane) - return FALSE; - return meta_kms_plane_is_transform_handled (crtc_kms->primary_plane, + return meta_kms_plane_is_transform_handled (crtc_kms->assigned_primary_plane, transform); } @@ -222,6 +341,8 @@ meta_crtc_kms_is_transform_handled (MetaCrtcNative *crtc_native, { MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc_native); + g_return_val_if_fail (crtc_kms->assigned_primary_plane, FALSE); + return is_transform_handled (crtc_kms, transform); } @@ -251,7 +372,7 @@ meta_crtc_kms_apply_transform (MetaCrtcKms *crtc_kms, if (!is_transform_handled (crtc_kms, hw_transform)) return; - meta_kms_plane_update_set_rotation (crtc_kms->primary_plane, + meta_kms_plane_update_set_rotation (crtc_kms->assigned_primary_plane, kms_plane_assignment, hw_transform); } @@ -268,7 +389,6 @@ meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms, MetaFixed16Rectangle src_rect; MtkRectangle dst_rect; MetaKmsCrtc *kms_crtc; - MetaKmsDevice *kms_device; MetaKmsPlane *primary_kms_plane; MetaKmsPlaneAssignment *plane_assignment; @@ -289,9 +409,7 @@ meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms, }; kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); - kms_device = meta_kms_crtc_get_device (kms_crtc); - primary_kms_plane = meta_kms_device_get_primary_plane_for (kms_device, - kms_crtc); + primary_kms_plane = crtc_kms->assigned_primary_plane; plane_assignment = meta_kms_update_assign_plane (kms_update, kms_crtc, primary_kms_plane, @@ -304,6 +422,12 @@ meta_crtc_kms_assign_primary_plane (MetaCrtcKms *crtc_kms, return plane_assignment; } +MetaKmsPlane * +meta_crtc_kms_get_assigned_cursor_plane (MetaCrtcKms *crtc_kms) +{ + return crtc_kms->assigned_cursor_plane; +} + static GList * generate_crtc_connector_list (MetaGpu *gpu, MetaCrtc *crtc) @@ -390,7 +514,9 @@ GArray * meta_crtc_kms_get_modifiers (MetaCrtcKms *crtc_kms, uint32_t format) { - return meta_kms_plane_get_modifiers_for_format (crtc_kms->primary_plane, + g_return_val_if_fail (crtc_kms->assigned_primary_plane, NULL); + + return meta_kms_plane_get_modifiers_for_format (crtc_kms->assigned_primary_plane, format); } @@ -405,7 +531,9 @@ meta_crtc_kms_get_modifiers (MetaCrtcKms *crtc_kms, GArray * meta_crtc_kms_copy_drm_format_list (MetaCrtcKms *crtc_kms) { - return meta_kms_plane_copy_drm_format_list (crtc_kms->primary_plane); + g_return_val_if_fail (crtc_kms->assigned_primary_plane, NULL); + + return meta_kms_plane_copy_drm_format_list (crtc_kms->assigned_primary_plane); } /** @@ -419,7 +547,9 @@ gboolean meta_crtc_kms_supports_format (MetaCrtcKms *crtc_kms, uint32_t drm_format) { - return meta_kms_plane_is_format_supported (crtc_kms->primary_plane, + g_return_val_if_fail (crtc_kms->assigned_primary_plane, FALSE); + + return meta_kms_plane_is_format_supported (crtc_kms->assigned_primary_plane, drm_format); } @@ -434,13 +564,8 @@ meta_crtc_kms_new (MetaGpuKms *gpu_kms, MetaKmsCrtc *kms_crtc) { MetaGpu *gpu = META_GPU (gpu_kms); - MetaKmsDevice *kms_device; MetaCrtcKms *crtc_kms; - MetaKmsPlane *primary_plane; - kms_device = meta_gpu_kms_get_kms_device (gpu_kms); - primary_plane = meta_kms_device_get_primary_plane_for (kms_device, - kms_crtc); crtc_kms = g_object_new (META_TYPE_CRTC_KMS, "id", (uint64_t) meta_kms_crtc_get_id (kms_crtc), "backend", meta_gpu_get_backend (gpu), @@ -448,7 +573,6 @@ meta_crtc_kms_new (MetaGpuKms *gpu_kms, NULL); crtc_kms->kms_crtc = kms_crtc; - crtc_kms->primary_plane = primary_plane; if (!kms_crtc_crtc_kms_quark) { @@ -475,6 +599,8 @@ meta_crtc_kms_class_init (MetaCrtcKmsClass *klass) crtc_class->get_gamma_lut_size = meta_crtc_kms_get_gamma_lut_size; crtc_class->get_gamma_lut = meta_crtc_kms_get_gamma_lut; crtc_class->set_gamma_lut = meta_crtc_kms_set_gamma_lut; + crtc_class->assign_extra = meta_crtc_kms_assign_extra; + crtc_class->set_config = meta_crtc_kms_set_config; crtc_native_class->is_transform_handled = meta_crtc_kms_is_transform_handled; crtc_native_class->is_hw_cursor_supported = meta_crtc_kms_is_hw_cursor_supported; diff --git a/src/backends/native/meta-crtc-kms.h b/src/backends/native/meta-crtc-kms.h index e45598afc..2df420e73 100644 --- a/src/backends/native/meta-crtc-kms.h +++ b/src/backends/native/meta-crtc-kms.h @@ -45,6 +45,8 @@ MetaKmsPlaneAssignment * meta_crtc_kms_assign_primary_plane (MetaCrtcKms MetaKmsUpdate *kms_update, MetaKmsAssignPlaneFlag flags); +MetaKmsPlane * meta_crtc_kms_get_assigned_cursor_plane (MetaCrtcKms *crtc_kms); + void meta_crtc_kms_set_mode (MetaCrtcKms *crtc_kms, MetaKmsUpdate *kms_update); diff --git a/src/backends/native/meta-kms-cursor-manager.c b/src/backends/native/meta-kms-cursor-manager.c index 3fbd2d9f0..b996ff712 100644 --- a/src/backends/native/meta-kms-cursor-manager.c +++ b/src/backends/native/meta-kms-cursor-manager.c @@ -45,6 +45,7 @@ typedef struct _CrtcStateImpl MetaKmsCursorManagerImpl *cursor_manager_impl; MetaKmsCrtc *crtc; + MetaKmsPlane *cursor_plane; graphene_rect_t layout; float scale; MetaMonitorTransform transform; @@ -97,6 +98,7 @@ find_crtc_state (MetaKmsCursorManagerImpl *cursor_manager_impl, static CrtcStateImpl * crtc_state_impl_new (MetaKmsCursorManagerImpl *cursor_manager_impl, MetaKmsCrtc *crtc, + MetaKmsPlane *cursor_plane, graphene_rect_t layout, float scale, MetaDrmBuffer *buffer) @@ -107,6 +109,7 @@ crtc_state_impl_new (MetaKmsCursorManagerImpl *cursor_manager_impl, g_atomic_ref_count_init (&crtc_state_impl->ref_count); crtc_state_impl->cursor_manager_impl = cursor_manager_impl; crtc_state_impl->crtc = crtc; + crtc_state_impl->cursor_plane = cursor_plane; crtc_state_impl->layout = layout; crtc_state_impl->scale = scale; crtc_state_impl->buffer = buffer; @@ -365,7 +368,7 @@ maybe_update_cursor_plane (MetaKmsCursorManagerImpl *cursor_manager_impl, meta_kms_update_realize (update, impl_device); } - cursor_plane = meta_kms_device_get_cursor_plane_for (device, crtc); + cursor_plane = crtc_state_impl->cursor_plane; if (should_have_cursor) { @@ -838,6 +841,7 @@ update_viewports_in_impl (MetaThreadImpl *thread_impl, crtc_state_impl = crtc_state_impl_new (cursor_manager_impl, crtc_layout->crtc, + crtc_layout->cursor_plane, crtc_layout->layout, crtc_layout->scale, g_steal_pointer (&old_crtc_state->buffer)); @@ -847,6 +851,7 @@ update_viewports_in_impl (MetaThreadImpl *thread_impl, crtc_state_impl = crtc_state_impl_new (cursor_manager_impl, crtc_layout->crtc, + crtc_layout->cursor_plane, crtc_layout->layout, crtc_layout->scale, NULL); diff --git a/src/backends/native/meta-kms-cursor-manager.h b/src/backends/native/meta-kms-cursor-manager.h index f4d35ed1a..0f4774ca4 100644 --- a/src/backends/native/meta-kms-cursor-manager.h +++ b/src/backends/native/meta-kms-cursor-manager.h @@ -28,6 +28,7 @@ typedef struct _MetaKmsCrtcLayout { MetaKmsCrtc *crtc; + MetaKmsPlane *cursor_plane; graphene_rect_t layout; float scale; } MetaKmsCrtcLayout; diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 55a48f667..7494563ca 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -1122,23 +1122,27 @@ meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native) MetaOnscreenNative *onscreen_native = META_ONSCREEN_NATIVE (framebuffer); MetaCrtc *crtc; + MetaCrtcKms *crtc_kms; MetaKmsCrtc *kms_crtc; + MetaKmsPlane *kms_plane; MtkRectangle view_layout; float view_scale; MetaKmsCrtcLayout crtc_layout; - renderer_native->pending_mode_set_views = - g_list_prepend (renderer_native->pending_mode_set_views, - stage_view); - meta_onscreen_native_invalidate (onscreen_native); crtc = meta_onscreen_native_get_crtc (onscreen_native); - kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc)); + crtc_kms = META_CRTC_KMS (crtc); + + kms_plane = meta_crtc_kms_get_assigned_cursor_plane (crtc_kms); + if (!kms_plane) + continue; + kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms); clutter_stage_view_get_layout (stage_view, &view_layout); view_scale = clutter_stage_view_get_scale (stage_view); crtc_layout = (MetaKmsCrtcLayout) { .crtc = kms_crtc, + .cursor_plane = kms_plane, .layout = GRAPHENE_RECT_INIT (view_layout.x, view_layout.y, view_layout.width, @@ -1146,6 +1150,11 @@ meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native) .scale = view_scale, }; g_array_append_val (crtc_layouts, crtc_layout); + + meta_onscreen_native_invalidate (onscreen_native); + renderer_native->pending_mode_set_views = + g_list_prepend (renderer_native->pending_mode_set_views, + stage_view); } } renderer_native->pending_mode_set = TRUE;