From 1c98f01a65a7b1ad980dbe1bb5129d36aec999e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 17 Jan 2020 21:08:02 +0100 Subject: [PATCH] renderer-native: Draw stage separately per CRTC Prior to this commit the stage was drawn separately for each logical monitor. This allowed to draw different parts of the stage with different transformations, e.g. with a different viewport to implement HiDPI support. Go even further and have one view per CRTC. This causes the stage to e.g. draw two mirrored monitors twice, instead of using the same framebuffer on both. This enables us to do two things: one is to support tiled monitors and monitor mirroring using the EGLStreams backend; the other is that it'll enable us to tie rendering directly to the CRTC it will render for. It is also a requirement for rendering being affected by CRTC state, such as gamma. It'll be possible to still inhibit re-drawing of the same content twice, but it should be implemented differently, so that it will still be possible to implement features requiring the CRTC split. https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042 --- clutter/clutter/clutter-stage.c | 63 +- src/backends/meta-renderer-view.c | 21 - src/backends/meta-renderer-view.h | 2 - src/backends/meta-renderer.c | 48 +- src/backends/meta-renderer.h | 7 +- .../meta-screen-cast-monitor-stream-src.c | 109 +-- src/backends/native/meta-crtc-kms.c | 15 +- src/backends/native/meta-crtc-kms.h | 2 - src/backends/native/meta-renderer-native.c | 637 +++++------------- .../x11/nested/meta-renderer-x11-nested.c | 32 +- .../x11/nested/meta-stage-x11-nested.c | 147 +--- 11 files changed, 313 insertions(+), 770 deletions(-) diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c index 57ffc78c8..25735c264 100644 --- a/clutter/clutter/clutter-stage.c +++ b/clutter/clutter/clutter-stage.c @@ -4476,49 +4476,42 @@ capture_view_into (ClutterStage *stage, cogl_object_unref (bitmap); } -static ClutterStageView * -get_view_at_rect (ClutterStage *stage, - cairo_rectangle_int_t *rect) -{ - ClutterStagePrivate *priv = stage->priv; - GList *views = _clutter_stage_window_get_views (priv->impl); - GList *l; - - for (l = views; l; l = l->next) - { - ClutterStageView *view = l->data; - cairo_rectangle_int_t view_layout; - cairo_region_t *region; - cairo_rectangle_int_t view_capture_rect; - - clutter_stage_view_get_layout (view, &view_layout); - region = cairo_region_create_rectangle (&view_layout); - cairo_region_intersect_rectangle (region, rect); - cairo_region_get_extents (region, &view_capture_rect); - cairo_region_destroy (region); - - if (view_capture_rect.width == 0 || view_capture_rect.height == 0) - continue; - - g_assert (view_capture_rect.width == rect->width && - view_capture_rect.height == rect->height); - return view; - } - - return NULL; -} - void clutter_stage_capture_into (ClutterStage *stage, gboolean paint, cairo_rectangle_int_t *rect, uint8_t *data) { - ClutterStageView *view; + ClutterStagePrivate *priv = stage->priv; + GList *l; int bpp = 4; + int stride; - view = get_view_at_rect (stage, rect); - capture_view_into (stage, paint, view, rect, data, rect->width * bpp); + stride = rect->width * 4; + + for (l = _clutter_stage_window_get_views (priv->impl); l; l = l->next) + { + ClutterStageView *view = l->data; + cairo_rectangle_int_t view_layout; + cairo_region_t *region; + cairo_rectangle_int_t capture_rect; + int x_offset, y_offset; + + clutter_stage_view_get_layout (view, &view_layout); + region = cairo_region_create_rectangle (&view_layout); + cairo_region_intersect_rectangle (region, rect); + + cairo_region_get_extents (region, &capture_rect); + cairo_region_destroy (region); + + x_offset = capture_rect.x - rect->x; + y_offset = capture_rect.y - rect->y; + + capture_view_into (stage, paint, view, + &capture_rect, + data + (x_offset * bpp) + (y_offset * stride), + stride); + } } /** diff --git a/src/backends/meta-renderer-view.c b/src/backends/meta-renderer-view.c index cab1f5f48..ae771f2de 100644 --- a/src/backends/meta-renderer-view.c +++ b/src/backends/meta-renderer-view.c @@ -39,7 +39,6 @@ enum { PROP_0, - PROP_MONITOR_INFO, PROP_TRANSFORM, PROP_LAST @@ -52,18 +51,11 @@ struct _MetaRendererView ClutterStageViewCogl parent; MetaMonitorTransform transform; - MetaLogicalMonitor *logical_monitor; }; G_DEFINE_TYPE (MetaRendererView, meta_renderer_view, CLUTTER_TYPE_STAGE_VIEW_COGL) -MetaLogicalMonitor * -meta_renderer_view_get_logical_monitor (MetaRendererView *view) -{ - return view->logical_monitor; -} - MetaMonitorTransform meta_renderer_view_get_transform (MetaRendererView *view) { @@ -146,9 +138,6 @@ meta_renderer_view_get_property (GObject *object, switch (prop_id) { - case PROP_MONITOR_INFO: - g_value_set_pointer (value, view->logical_monitor); - break; case PROP_TRANSFORM: g_value_set_uint (value, view->transform); break; @@ -168,9 +157,6 @@ meta_renderer_view_set_property (GObject *object, switch (prop_id) { - case PROP_MONITOR_INFO: - view->logical_monitor = g_value_get_pointer (value); - break; case PROP_TRANSFORM: meta_renderer_view_set_transform (view, g_value_get_uint (value)); break; @@ -199,13 +185,6 @@ meta_renderer_view_class_init (MetaRendererViewClass *klass) object_class->get_property = meta_renderer_view_get_property; object_class->set_property = meta_renderer_view_set_property; - obj_props[PROP_MONITOR_INFO] = - g_param_spec_pointer ("logical-monitor", - "MetaLogicalMonitor", - "The logical monitor of the view", - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS | - G_PARAM_CONSTRUCT_ONLY); obj_props[PROP_TRANSFORM] = g_param_spec_uint ("transform", "Transform", diff --git a/src/backends/meta-renderer-view.h b/src/backends/meta-renderer-view.h index 650341479..f601de534 100644 --- a/src/backends/meta-renderer-view.h +++ b/src/backends/meta-renderer-view.h @@ -26,8 +26,6 @@ G_DECLARE_FINAL_TYPE (MetaRendererView, meta_renderer_view, META, RENDERER_VIEW, ClutterStageViewCogl) -MetaLogicalMonitor *meta_renderer_view_get_logical_monitor (MetaRendererView *view); - MetaMonitorTransform meta_renderer_view_get_transform (MetaRendererView *view); #endif /* META_RENDERER_VIEW_H */ diff --git a/src/backends/meta-renderer.c b/src/backends/meta-renderer.c index 24688577c..3846bde7d 100644 --- a/src/backends/meta-renderer.c +++ b/src/backends/meta-renderer.c @@ -47,6 +47,7 @@ #include #include "backends/meta-backend-private.h" +#include "backends/meta-logical-monitor.h" enum { @@ -93,10 +94,14 @@ meta_renderer_create_cogl_renderer (MetaRenderer *renderer) static MetaRendererView * meta_renderer_create_view (MetaRenderer *renderer, - MetaLogicalMonitor *logical_monitor) + MetaLogicalMonitor *logical_monitor, + MetaOutput *output, + MetaCrtc *crtc) { return META_RENDERER_GET_CLASS (renderer)->create_view (renderer, - logical_monitor); + logical_monitor, + output, + crtc); } /** @@ -114,6 +119,21 @@ meta_renderer_rebuild_views (MetaRenderer *renderer) return META_RENDERER_GET_CLASS (renderer)->rebuild_views (renderer); } +static void +create_crtc_view (MetaLogicalMonitor *logical_monitor, + MetaMonitor *monitor, + MetaOutput *output, + MetaCrtc *crtc, + gpointer user_data) +{ + MetaRenderer *renderer = user_data; + MetaRendererPrivate *priv = meta_renderer_get_instance_private (renderer); + MetaRendererView *view; + + view = meta_renderer_create_view (renderer, logical_monitor, output, crtc); + priv->views = g_list_append (priv->views, view); +} + static void meta_renderer_real_rebuild_views (MetaRenderer *renderer) { @@ -132,10 +152,10 @@ meta_renderer_real_rebuild_views (MetaRenderer *renderer) for (l = logical_monitors; l; l = l->next) { MetaLogicalMonitor *logical_monitor = l->data; - MetaRendererView *view; - view = meta_renderer_create_view (renderer, logical_monitor); - priv->views = g_list_append (priv->views, view); + meta_logical_monitor_foreach_crtc (logical_monitor, + create_crtc_view, + renderer); } } @@ -168,24 +188,6 @@ meta_renderer_get_views (MetaRenderer *renderer) return priv->views; } -MetaRendererView * -meta_renderer_get_view_from_logical_monitor (MetaRenderer *renderer, - MetaLogicalMonitor *logical_monitor) -{ - GList *l; - - for (l = meta_renderer_get_views (renderer); l; l = l->next) - { - MetaRendererView *view = l->data; - - if (meta_renderer_view_get_logical_monitor (view) == - logical_monitor) - return view; - } - - return NULL; -} - gboolean meta_renderer_is_hardware_accelerated (MetaRenderer *renderer) { diff --git a/src/backends/meta-renderer.h b/src/backends/meta-renderer.h index f5182e0eb..e6160922a 100644 --- a/src/backends/meta-renderer.h +++ b/src/backends/meta-renderer.h @@ -42,7 +42,9 @@ struct _MetaRendererClass CoglRenderer * (* create_cogl_renderer) (MetaRenderer *renderer); MetaRendererView * (* create_view) (MetaRenderer *renderer, - MetaLogicalMonitor *logical_monitor); + MetaLogicalMonitor *logical_monitor, + MetaOutput *output, + MetaCrtc *crtc); void (* rebuild_views) (MetaRenderer *renderer); }; @@ -58,9 +60,6 @@ void meta_renderer_set_legacy_view (MetaRenderer *renderer, META_EXPORT_TEST GList * meta_renderer_get_views (MetaRenderer *renderer); -MetaRendererView * meta_renderer_get_view_from_logical_monitor (MetaRenderer *renderer, - MetaLogicalMonitor *logical_monitor); - gboolean meta_renderer_is_hardware_accelerated (MetaRenderer *renderer); #endif /* META_RENDERER_H */ diff --git a/src/backends/meta-screen-cast-monitor-stream-src.c b/src/backends/meta-screen-cast-monitor-stream-src.c index 5d9dadc8c..902ae545b 100644 --- a/src/backends/meta-screen-cast-monitor-stream-src.c +++ b/src/backends/meta-screen-cast-monitor-stream-src.c @@ -42,9 +42,9 @@ struct _MetaScreenCastMonitorStreamSrc MetaScreenCastStreamSrc parent; gboolean cursor_bitmap_invalid; + gboolean hw_cursor_inhibited; - MetaStageWatch *paint_watch; - MetaStageWatch *after_paint_watch; + GList *watches; gulong cursor_moved_handler_id; gulong cursor_changed_handler_id; @@ -226,9 +226,13 @@ inhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src) MetaCursorRenderer *cursor_renderer; MetaHwCursorInhibitor *inhibitor; + g_return_if_fail (!monitor_src->hw_cursor_inhibited); + cursor_renderer = get_cursor_renderer (monitor_src); inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src); meta_cursor_renderer_add_hw_cursor_inhibitor (cursor_renderer, inhibitor); + + monitor_src->hw_cursor_inhibited = TRUE; } static void @@ -237,9 +241,53 @@ uninhibit_hw_cursor (MetaScreenCastMonitorStreamSrc *monitor_src) MetaCursorRenderer *cursor_renderer; MetaHwCursorInhibitor *inhibitor; + g_return_if_fail (monitor_src->hw_cursor_inhibited); + cursor_renderer = get_cursor_renderer (monitor_src); inhibitor = META_HW_CURSOR_INHIBITOR (monitor_src); meta_cursor_renderer_remove_hw_cursor_inhibitor (cursor_renderer, inhibitor); + + monitor_src->hw_cursor_inhibited = FALSE; +} + +static void +add_view_painted_watches (MetaScreenCastMonitorStreamSrc *monitor_src, + MetaStageWatchPhase watch_phase) +{ + MetaBackend *backend = get_backend (monitor_src); + MetaRenderer *renderer = meta_backend_get_renderer (backend); + ClutterStage *stage; + MetaStage *meta_stage; + MetaMonitor *monitor; + MetaLogicalMonitor *logical_monitor; + MetaRectangle logical_monitor_layout; + GList *l; + + stage = get_stage (monitor_src); + meta_stage = META_STAGE (stage); + monitor = get_monitor (monitor_src); + logical_monitor = meta_monitor_get_logical_monitor (monitor); + logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor); + + for (l = meta_renderer_get_views (renderer); l; l = l->next) + { + MetaRendererView *view = l->data; + MetaRectangle view_layout; + + clutter_stage_view_get_layout (CLUTTER_STAGE_VIEW (view), &view_layout); + if (meta_rectangle_overlap (&logical_monitor_layout, &view_layout)) + { + MetaStageWatch *watch; + + watch = meta_stage_watch_view (meta_stage, + CLUTTER_STAGE_VIEW (view), + watch_phase, + stage_painted, + monitor_src); + + monitor_src->watches = g_list_prepend (monitor_src->watches, watch); + } + } } static void @@ -248,28 +296,12 @@ meta_screen_cast_monitor_stream_src_enable (MetaScreenCastStreamSrc *src) MetaScreenCastMonitorStreamSrc *monitor_src = META_SCREEN_CAST_MONITOR_STREAM_SRC (src); MetaBackend *backend = get_backend (monitor_src); - MetaRenderer *renderer = meta_backend_get_renderer (backend); MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); - MetaRendererView *view; - MetaMonitor *monitor; - MetaLogicalMonitor *logical_monitor; - MetaStage *meta_stage; - ClutterStageView *stage_view; ClutterStage *stage; MetaScreenCastStream *stream; stream = meta_screen_cast_stream_src_get_stream (src); stage = get_stage (monitor_src); - meta_stage = META_STAGE (stage); - monitor = get_monitor (monitor_src); - logical_monitor = meta_monitor_get_logical_monitor (monitor); - view = meta_renderer_get_view_from_logical_monitor (renderer, - logical_monitor); - - if (view) - stage_view = CLUTTER_STAGE_VIEW (view); - else - stage_view = NULL; switch (meta_screen_cast_stream_get_cursor_mode (stream)) { @@ -284,21 +316,13 @@ meta_screen_cast_monitor_stream_src_enable (MetaScreenCastStreamSrc *src) monitor_src); G_GNUC_FALLTHROUGH; case META_SCREEN_CAST_CURSOR_MODE_HIDDEN: - monitor_src->paint_watch = - meta_stage_watch_view (meta_stage, - stage_view, - META_STAGE_WATCH_AFTER_ACTOR_PAINT, - stage_painted, - monitor_src); + add_view_painted_watches (monitor_src, + META_STAGE_WATCH_AFTER_ACTOR_PAINT); break; case META_SCREEN_CAST_CURSOR_MODE_EMBEDDED: inhibit_hw_cursor (monitor_src); - monitor_src->after_paint_watch = - meta_stage_watch_view (meta_stage, - stage_view, - META_STAGE_WATCH_AFTER_PAINT, - stage_painted, - monitor_src); + add_view_painted_watches (monitor_src, + META_STAGE_WATCH_AFTER_PAINT); break; } @@ -314,22 +338,21 @@ meta_screen_cast_monitor_stream_src_disable (MetaScreenCastStreamSrc *src) MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend); ClutterStage *stage; MetaStage *meta_stage; + GList *l; stage = get_stage (monitor_src); meta_stage = META_STAGE (stage); - if (monitor_src->paint_watch) + for (l = monitor_src->watches; l; l = l->next) { - meta_stage_remove_watch (meta_stage, monitor_src->paint_watch); - monitor_src->paint_watch = NULL; - } + MetaStageWatch *watch = l->data; - if (monitor_src->after_paint_watch) - { - meta_stage_remove_watch (meta_stage, monitor_src->after_paint_watch); - monitor_src->after_paint_watch = NULL; - uninhibit_hw_cursor (monitor_src); + meta_stage_remove_watch (meta_stage, watch); } + g_clear_pointer (&monitor_src->watches, g_list_free); + + if (monitor_src->hw_cursor_inhibited) + uninhibit_hw_cursor (monitor_src); g_clear_signal_handler (&monitor_src->cursor_moved_handler_id, cursor_tracker); @@ -367,13 +390,11 @@ meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc MetaBackend *backend = get_backend (monitor_src); MetaCursorRenderer *cursor_renderer = meta_backend_get_cursor_renderer (backend); - MetaRenderer *renderer = meta_backend_get_renderer (backend); MetaCursorSprite *cursor_sprite; MetaMonitor *monitor; MetaLogicalMonitor *logical_monitor; MetaRectangle logical_monitor_layout; graphene_rect_t logical_monitor_rect; - MetaRendererView *view; float view_scale; graphene_point_t cursor_position; int x, y; @@ -393,10 +414,8 @@ meta_screen_cast_monitor_stream_src_set_cursor_metadata (MetaScreenCastStreamSrc logical_monitor_rect = meta_rectangle_to_graphene_rect (&logical_monitor_layout); - view = meta_renderer_get_view_from_logical_monitor (renderer, - logical_monitor); - if (view) - view_scale = clutter_stage_view_get_scale (CLUTTER_STAGE_VIEW (view)); + if (meta_is_stage_views_scaled ()) + view_scale = meta_logical_monitor_get_scale (logical_monitor); else view_scale = 1.0; diff --git a/src/backends/native/meta-crtc-kms.c b/src/backends/native/meta-crtc-kms.c index 1ec6654f8..2d570b2de 100644 --- a/src/backends/native/meta-crtc-kms.c +++ b/src/backends/native/meta-crtc-kms.c @@ -76,14 +76,10 @@ meta_crtc_kms_apply_transform (MetaCrtc *crtc, void meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc, - MetaMonitor *monitor, - MetaOutput *output, uint32_t fb_id, MetaKmsUpdate *kms_update) { - MetaMonitorMode *monitor_mode; MetaCrtcConfig *crtc_config; - int crtc_x, crtc_y; MetaFixed16Rectangle src_rect; MetaFixed16Rectangle dst_rect; MetaKmsAssignPlaneFlag flags; @@ -94,17 +90,10 @@ meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc, crtc_config = crtc->config; - monitor_mode = meta_monitor_get_current_mode (monitor); - meta_monitor_calculate_crtc_pos (monitor, - monitor_mode, - output, - crtc_config->transform, - &crtc_x, - &crtc_y); src_rect = (MetaFixed16Rectangle) { - .x = meta_fixed_16_from_int (crtc_x), - .y = meta_fixed_16_from_int (crtc_y), + .x = meta_fixed_16_from_int (0), + .y = meta_fixed_16_from_int (0), .width = meta_fixed_16_from_int (crtc_config->mode->width), .height = meta_fixed_16_from_int (crtc_config->mode->height), }; diff --git a/src/backends/native/meta-crtc-kms.h b/src/backends/native/meta-crtc-kms.h index 4b2df3cfa..898622478 100644 --- a/src/backends/native/meta-crtc-kms.h +++ b/src/backends/native/meta-crtc-kms.h @@ -38,8 +38,6 @@ void meta_crtc_kms_apply_transform (MetaCrtc *crtc, MetaKmsPlaneAssignment *kms_plane_assignment); void meta_crtc_kms_assign_primary_plane (MetaCrtc *crtc, - MetaMonitor *monitor, - MetaOutput *output, uint32_t fb_id, MetaKmsUpdate *kms_update); diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index 0de4ea3dc..19786b196 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -181,9 +181,10 @@ typedef struct _MetaOnscreenNative { MetaRendererNative *renderer_native; MetaGpuKms *render_gpu; - MetaLogicalMonitor *logical_monitor; + MetaOutput *output; + MetaCrtc *crtc; - GHashTable *secondary_gpu_states; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; struct { struct gbm_surface *surface; @@ -263,8 +264,7 @@ static MetaEgl * meta_renderer_native_get_egl (MetaRendererNative *renderer_native); static void -free_current_secondary_bo (MetaGpuKms *gpu_kms, - MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state); +free_current_secondary_bo (CoglOnscreen *onscreen); static gboolean cogl_pixel_format_from_drm_format (uint32_t drm_format, @@ -320,24 +320,6 @@ meta_create_renderer_native_gpu_data (MetaGpuKms *gpu_kms) return g_new0 (MetaRendererNativeGpuData, 1); } -static MetaOnscreenNativeSecondaryGpuState * -meta_onscreen_native_get_secondary_gpu_state (MetaOnscreenNative *onscreen_native, - MetaGpuKms *gpu_kms) -{ - return g_hash_table_lookup (onscreen_native->secondary_gpu_states, gpu_kms); -} - -static MetaOnscreenNativeSecondaryGpuState * -get_secondary_gpu_state (CoglOnscreen *onscreen, - MetaGpuKms *gpu_kms) -{ - CoglOnscreenEGL *onscreen_egl = onscreen->winsys; - MetaOnscreenNative *onscreen_native = onscreen_egl->platform; - - return meta_onscreen_native_get_secondary_gpu_state (onscreen_native, - gpu_kms); -} - static MetaEgl * meta_renderer_native_get_egl (MetaRendererNative *renderer_native) { @@ -353,138 +335,56 @@ meta_onscreen_native_get_egl (MetaOnscreenNative *onscreen_native) } static GArray * -get_supported_kms_modifiers (CoglOnscreen *onscreen, - MetaGpu *gpu, - uint32_t format) +get_supported_kms_modifiers (MetaCrtc *crtc, + uint32_t format) { - CoglOnscreenEGL *onscreen_egl = onscreen->winsys; - MetaOnscreenNative *onscreen_native = onscreen_egl->platform; - MetaLogicalMonitor *logical_monitor = onscreen_native->logical_monitor; GArray *modifiers; - GArray *base_mods; - GList *l_crtc; - MetaCrtc *base_crtc = NULL; - GList *other_crtcs = NULL; + GArray *crtc_mods; unsigned int i; - if (!logical_monitor) + crtc_mods = meta_crtc_kms_get_modifiers (crtc, format); + if (!crtc_mods) return NULL; - /* Find our base CRTC to intersect against. */ - for (l_crtc = meta_gpu_get_crtcs (gpu); l_crtc; l_crtc = l_crtc->next) - { - MetaCrtc *crtc = l_crtc->data; - - if (crtc->logical_monitor != logical_monitor) - continue; - - if (!base_crtc) - base_crtc = crtc; - else if (crtc == base_crtc) - continue; - else if (g_list_index (other_crtcs, crtc) == -1) - other_crtcs = g_list_append (other_crtcs, crtc); - } - - if (!base_crtc) - goto out; - - base_mods = meta_crtc_kms_get_modifiers (base_crtc, format); - if (!base_mods) - goto out; - - /* - * If this is the only CRTC we have, we don't need to intersect the sets of - * modifiers. - */ - if (other_crtcs == NULL) - { - modifiers = g_array_sized_new (FALSE, FALSE, sizeof (uint64_t), - base_mods->len); - g_array_append_vals (modifiers, base_mods->data, base_mods->len); - return modifiers; - } - modifiers = g_array_new (FALSE, FALSE, sizeof (uint64_t)); /* * For each modifier from base_crtc, check if it's available on all other * CRTCs. */ - for (i = 0; i < base_mods->len; i++) + for (i = 0; i < crtc_mods->len; i++) { - uint64_t modifier = g_array_index (base_mods, uint64_t, i); - gboolean found_everywhere = TRUE; - GList *k; + uint64_t modifier = g_array_index (crtc_mods, uint64_t, i); - /* Check if we have the same modifier available for all CRTCs. */ - for (k = other_crtcs; k; k = k->next) - { - MetaCrtc *crtc = k->data; - GArray *crtc_mods; - unsigned int m; - gboolean found_here = FALSE; - - if (crtc->logical_monitor != logical_monitor) - continue; - - crtc_mods = meta_crtc_kms_get_modifiers (crtc, format); - if (!crtc_mods) - { - g_array_free (modifiers, TRUE); - goto out; - } - - for (m = 0; m < crtc_mods->len; m++) - { - uint64_t local_mod = g_array_index (crtc_mods, uint64_t, m); - - if (local_mod == modifier) - { - found_here = TRUE; - break; - } - } - - if (!found_here) - { - found_everywhere = FALSE; - break; - } - } - - if (found_everywhere) - g_array_append_val (modifiers, modifier); + g_array_append_val (modifiers, modifier); } if (modifiers->len == 0) { g_array_free (modifiers, TRUE); - goto out; + return NULL; } return modifiers; - -out: - g_list_free (other_crtcs); - return NULL; } static GArray * get_supported_egl_modifiers (CoglOnscreen *onscreen, - MetaGpu *gpu, + MetaCrtc *crtc, uint32_t format) { CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaRendererNative *renderer_native = onscreen_native->renderer_native; MetaEgl *egl = meta_onscreen_native_get_egl (onscreen_native); + MetaGpu *gpu; MetaRendererNativeGpuData *renderer_gpu_data; EGLint num_modifiers; GArray *modifiers; GError *error = NULL; gboolean ret; + gpu = meta_crtc_get_gpu (crtc); renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, META_GPU_KMS (gpu)); @@ -523,149 +423,33 @@ get_supported_modifiers (CoglOnscreen *onscreen, { CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; - MetaLogicalMonitor *logical_monitor = onscreen_native->logical_monitor; - GArray *modifiers = NULL; - GArray *gpu_mods; - GList *l_monitor; - unsigned int i; - - if (!logical_monitor) - return NULL; - - /* Find our base CRTC to intersect against. */ - for (l_monitor = meta_logical_monitor_get_monitors (logical_monitor); - l_monitor; - l_monitor = l_monitor->next) - { - MetaMonitor *monitor = l_monitor->data; - MetaGpu *gpu = meta_monitor_get_gpu (monitor); - - if (gpu == META_GPU (onscreen_native->render_gpu)) - gpu_mods = get_supported_kms_modifiers (onscreen, gpu, format); - else - gpu_mods = get_supported_egl_modifiers (onscreen, gpu, format); - - if (!gpu_mods) - { - g_array_free (modifiers, TRUE); - return NULL; - } - - if (!modifiers) - { - modifiers = gpu_mods; - continue; - } - - for (i = 0; i < modifiers->len; i++) - { - uint64_t modifier = g_array_index (modifiers, uint64_t, i); - gboolean found = FALSE; - unsigned int m; - - for (m = 0; m < gpu_mods->len; m++) - { - uint64_t gpu_mod = g_array_index (gpu_mods, uint64_t, m); - - if (gpu_mod == modifier) - { - found = TRUE; - break; - } - } - - if (!found) - { - g_array_remove_index_fast (modifiers, i); - i--; - } - } - - g_array_free (gpu_mods, TRUE); - } - - if (modifiers && modifiers->len == 0) - { - g_array_free (modifiers, TRUE); - return NULL; - } - - return modifiers; -} - -typedef struct _GetSupportedKmsFormatsData -{ - GArray *formats; + MetaCrtc *crtc = onscreen_native->crtc; MetaGpu *gpu; -} GetSupportedKmsFormatsData; + g_autoptr (GArray) modifiers = NULL; -static void -get_supported_kms_formats_crtc_func (MetaLogicalMonitor *logical_monitor, - MetaMonitor *monitor, - MetaOutput *output, - MetaCrtc *crtc, - gpointer user_data) -{ - GetSupportedKmsFormatsData *data = user_data; - gboolean supported = TRUE; - unsigned int i; + gpu = meta_crtc_get_gpu (crtc); + if (gpu == META_GPU (onscreen_native->render_gpu)) + modifiers = get_supported_kms_modifiers (crtc, format); + else + modifiers = get_supported_egl_modifiers (onscreen, crtc, format); - if (crtc->gpu != data->gpu) - return; - - if (!data->formats) - { - /* MetaCrtcKms guarantees a non-empty list. */ - data->formats = meta_crtc_kms_copy_drm_format_list (crtc); - - return; - } - - /* formats must be supported by all other CRTCs too */ - for (i = 0; i < data->formats->len; i++) - { - uint32_t drm_format = g_array_index (data->formats, uint32_t, i); - - if (!meta_crtc_kms_supports_format (crtc, drm_format)) - { - supported = FALSE; - break; - } - } - - if (!supported) - g_array_remove_index_fast (data->formats, i--); + return g_steal_pointer (&modifiers); } static GArray * -get_supported_kms_formats (CoglOnscreen *onscreen, - MetaGpu *gpu) +get_supported_kms_formats (CoglOnscreen *onscreen) { CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; - MetaLogicalMonitor *logical_monitor = onscreen_native->logical_monitor; - GetSupportedKmsFormatsData data = { - .formats = NULL, - .gpu = gpu - }; + MetaCrtc *crtc = onscreen_native->crtc; - meta_logical_monitor_foreach_crtc (logical_monitor, - get_supported_kms_formats_crtc_func, - &data); - if (data.formats->len == 0) - { - g_array_free (data.formats, TRUE); - data.formats = NULL; - } - - return data.formats; + return meta_crtc_kms_copy_drm_format_list (crtc); } static gboolean init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative *renderer_native, CoglOnscreen *onscreen, MetaRendererNativeGpuData *renderer_gpu_data, - MetaGpuKms *gpu_kms, GError **error) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); @@ -677,6 +461,7 @@ init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative *renderer_nat struct gbm_surface *gbm_surface; EGLSurface egl_surface; MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + MetaGpuKms *gpu_kms; width = cogl_framebuffer_get_width (framebuffer); height = cogl_framebuffer_get_height (framebuffer); @@ -708,13 +493,13 @@ init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative *renderer_nat secondary_gpu_state = g_new0 (MetaOnscreenNativeSecondaryGpuState, 1); + gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc)); secondary_gpu_state->gpu_kms = gpu_kms; secondary_gpu_state->renderer_gpu_data = renderer_gpu_data; secondary_gpu_state->gbm.surface = gbm_surface; secondary_gpu_state->egl_surface = egl_surface; - g_hash_table_insert (onscreen_native->secondary_gpu_states, - gpu_kms, secondary_gpu_state); + onscreen_native->secondary_gpu_state = secondary_gpu_state; return TRUE; } @@ -734,7 +519,6 @@ secondary_gpu_state_free (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_sta { MetaBackend *backend = meta_get_backend (); MetaEgl *egl = meta_backend_get_egl (backend); - MetaGpuKms *gpu_kms = secondary_gpu_state->gpu_kms; if (secondary_gpu_state->egl_surface != EGL_NO_SURFACE) { @@ -747,7 +531,7 @@ secondary_gpu_state_free (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_sta NULL); } - free_current_secondary_bo (gpu_kms, secondary_gpu_state); + g_clear_object (&secondary_gpu_state->gbm.current_fb); g_clear_object (&secondary_gpu_state->gbm.next_fb); g_clear_pointer (&secondary_gpu_state->gbm.surface, gbm_surface_destroy); @@ -757,8 +541,7 @@ secondary_gpu_state_free (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_sta } static uint32_t -pick_secondary_gpu_framebuffer_format_for_cpu (CoglOnscreen *onscreen, - MetaGpu *gpu) +pick_secondary_gpu_framebuffer_format_for_cpu (CoglOnscreen *onscreen) { /* * cogl_framebuffer_read_pixels_into_bitmap () supported formats in @@ -784,7 +567,7 @@ pick_secondary_gpu_framebuffer_format_for_cpu (CoglOnscreen *onscreen, unsigned int i; uint32_t drm_format; - formats = get_supported_kms_formats (onscreen, gpu); + formats = get_supported_kms_formats (onscreen); /* Check if any of our preferred formats are supported. */ for (k = 0; k < G_N_ELEMENTS (preferred_formats); k++) @@ -822,20 +605,19 @@ static gboolean init_secondary_gpu_state_cpu_copy_mode (MetaRendererNative *renderer_native, CoglOnscreen *onscreen, MetaRendererNativeGpuData *renderer_gpu_data, - MetaGpuKms *gpu_kms, GError **error) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + MetaGpuKms *gpu_kms; int width, height; unsigned int i; uint32_t drm_format; MetaDrmFormatBuf tmp; - drm_format = pick_secondary_gpu_framebuffer_format_for_cpu (onscreen, - META_GPU (gpu_kms)); + drm_format = pick_secondary_gpu_framebuffer_format_for_cpu (onscreen); if (drm_format == DRM_FORMAT_INVALID) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -846,6 +628,7 @@ init_secondary_gpu_state_cpu_copy_mode (MetaRendererNative *renderer_nat width = cogl_framebuffer_get_width (framebuffer); height = cogl_framebuffer_get_height (framebuffer); + gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc)); g_debug ("Secondary GPU %s using DRM format '%s' (0x%x) for a %dx%d output.", meta_gpu_kms_get_file_path (gpu_kms), meta_drm_format_to_string (&tmp, drm_format), @@ -879,8 +662,7 @@ init_secondary_gpu_state_cpu_copy_mode (MetaRendererNative *renderer_nat secondary_gpu_state->import_status = META_SHARED_FRAMEBUFFER_IMPORT_STATUS_NONE; - g_hash_table_insert (onscreen_native->secondary_gpu_states, - gpu_kms, secondary_gpu_state); + onscreen_native->secondary_gpu_state = secondary_gpu_state; return TRUE; } @@ -888,13 +670,15 @@ init_secondary_gpu_state_cpu_copy_mode (MetaRendererNative *renderer_nat static gboolean init_secondary_gpu_state (MetaRendererNative *renderer_native, CoglOnscreen *onscreen, - MetaGpuKms *gpu_kms, GError **error) { + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaGpu *gpu = meta_crtc_get_gpu (onscreen_native->crtc); MetaRendererNativeGpuData *renderer_gpu_data; renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native, - gpu_kms); + META_GPU_KMS (gpu)); switch (renderer_gpu_data->secondary.copy_mode) { @@ -902,7 +686,6 @@ init_secondary_gpu_state (MetaRendererNative *renderer_native, if (!init_secondary_gpu_state_gpu_copy_mode (renderer_native, onscreen, renderer_gpu_data, - gpu_kms, error)) return FALSE; break; @@ -917,7 +700,6 @@ init_secondary_gpu_state (MetaRendererNative *renderer_native, if (!init_secondary_gpu_state_cpu_copy_mode (renderer_native, onscreen, renderer_gpu_data, - gpu_kms, error)) return FALSE; break; @@ -989,9 +771,16 @@ flush_pending_swap_notify_idle (void *user_data) } static void -free_current_secondary_bo (MetaGpuKms *gpu_kms, - MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state) +free_current_secondary_bo (CoglOnscreen *onscreen) { + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + + secondary_gpu_state = onscreen_native->secondary_gpu_state; + if (!secondary_gpu_state) + return; + g_clear_object (&secondary_gpu_state->gbm.current_fb); } @@ -1002,10 +791,7 @@ free_current_bo (CoglOnscreen *onscreen) MetaOnscreenNative *onscreen_native = onscreen_egl->platform; g_clear_object (&onscreen_native->gbm.current_fb); - - g_hash_table_foreach (onscreen_native->secondary_gpu_states, - (GHFunc) free_current_secondary_bo, - NULL); + free_current_secondary_bo (onscreen); } static void @@ -1292,9 +1078,16 @@ meta_renderer_native_egl_cleanup_context (CoglDisplay *cogl_display) } static void -swap_secondary_drm_fb (MetaGpuKms *gpu_kms, - MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state) +swap_secondary_drm_fb (CoglOnscreen *onscreen) { + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + + secondary_gpu_state = onscreen_native->secondary_gpu_state; + if (!secondary_gpu_state) + return; + g_set_object (&secondary_gpu_state->gbm.current_fb, secondary_gpu_state->gbm.next_fb); g_clear_object (&secondary_gpu_state->gbm.next_fb); @@ -1311,9 +1104,7 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen) g_set_object (&onscreen_native->gbm.current_fb, onscreen_native->gbm.next_fb); g_clear_object (&onscreen_native->gbm.next_fb); - g_hash_table_foreach (onscreen_native->secondary_gpu_states, - (GHFunc) swap_secondary_drm_fb, - NULL); + swap_secondary_drm_fb (onscreen); } static void @@ -1354,9 +1145,9 @@ notify_view_crtc_presented (MetaRendererView *view, gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (crtc)); if (gpu_kms != render_gpu) { - MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; + MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state = + onscreen_native->secondary_gpu_state; - secondary_gpu_state = get_secondary_gpu_state (onscreen, gpu_kms); secondary_gpu_state->pending_flips--; } @@ -1555,8 +1346,6 @@ queue_dummy_power_save_page_flip (CoglOnscreen *onscreen) static void meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, MetaRendererView *view, - MetaMonitor *monitor, - MetaOutput *output, MetaCrtc *crtc, MetaKmsUpdate *kms_update) { @@ -1584,12 +1373,11 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, } else { - secondary_gpu_state = get_secondary_gpu_state (onscreen, gpu_kms); + secondary_gpu_state = onscreen_native->secondary_gpu_state; fb_id = meta_drm_buffer_get_fb_id (secondary_gpu_state->gbm.next_fb); } - meta_crtc_kms_assign_primary_plane (crtc, monitor, output, - fb_id, kms_update); + meta_crtc_kms_assign_primary_plane (crtc, fb_id, kms_update); meta_crtc_kms_page_flip (crtc, &page_flip_feedback, g_object_ref (view), @@ -1614,23 +1402,18 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen, } } -typedef struct _SetCrtcModeData -{ - MetaRendererNativeGpuData *renderer_gpu_data; - MetaOnscreenNative *onscreen_native; - MetaKmsUpdate *kms_update; -} SetCrtcModeData; - static void -set_crtc_mode (MetaLogicalMonitor *logical_monitor, - MetaMonitor *monitor, - MetaOutput *output, - MetaCrtc *crtc, - gpointer user_data) +meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen, + MetaRendererNativeGpuData *renderer_gpu_data, + MetaKmsUpdate *kms_update) { - SetCrtcModeData *data = user_data; + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; - switch (data->renderer_gpu_data->mode) + COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeSetCrtcModes, + "Onscreen (set CRTC modes)"); + + switch (renderer_gpu_data->mode) { case META_RENDERER_NATIVE_MODE_GBM: break; @@ -1639,63 +1422,16 @@ set_crtc_mode (MetaLogicalMonitor *logical_monitor, { uint32_t fb_id; - fb_id = data->onscreen_native->egl.dumb_fb.fb_id; - meta_crtc_kms_assign_primary_plane (crtc, monitor, output, - fb_id, data->kms_update); + fb_id = onscreen_native->egl.dumb_fb.fb_id; + meta_crtc_kms_assign_primary_plane (onscreen_native->crtc, + fb_id, kms_update); break; } #endif } - meta_crtc_kms_set_mode (crtc, data->kms_update); - meta_output_kms_set_underscan (output, data->kms_update); -} - -static void -meta_onscreen_native_set_crtc_modes (CoglOnscreen *onscreen, - MetaRendererNativeGpuData *renderer_gpu_data, - MetaKmsUpdate *kms_update) -{ - CoglOnscreenEGL *onscreen_egl = onscreen->winsys; - MetaOnscreenNative *onscreen_native = onscreen_egl->platform; - MetaRendererView *view = onscreen_native->view; - MetaLogicalMonitor *logical_monitor; - SetCrtcModeData data; - - COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeSetCrtcModes, - "Onscreen (set CRTC modes)"); - - logical_monitor = meta_renderer_view_get_logical_monitor (view); - data = (SetCrtcModeData) { - .renderer_gpu_data = renderer_gpu_data, - .onscreen_native = onscreen_native, - .kms_update = kms_update, - }; - meta_logical_monitor_foreach_crtc (logical_monitor, set_crtc_mode, &data); -} - -typedef struct _FlipCrtcData -{ - MetaRendererView *view; - CoglOnscreen *onscreen; - MetaKmsUpdate *kms_update; -} FlipCrtcData; - -static void -flip_crtc (MetaLogicalMonitor *logical_monitor, - MetaMonitor *monitor, - MetaOutput *output, - MetaCrtc *crtc, - gpointer user_data) -{ - FlipCrtcData *data = user_data; - - meta_onscreen_native_flip_crtc (data->onscreen, - data->view, - monitor, - output, - crtc, - data->kms_update); + meta_crtc_kms_set_mode (onscreen_native->crtc, kms_update); + meta_output_kms_set_underscan (onscreen_native->output, kms_update); } static void @@ -1710,7 +1446,6 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen, MetaMonitorManager *monitor_manager = meta_backend_get_monitor_manager (meta_renderer_get_backend (renderer)); MetaPowerSave power_save_mode; - MetaLogicalMonitor *logical_monitor; COGL_TRACE_BEGIN_SCOPED (MetaOnscreenNativeFlipCrtcs, "Onscreen (flip CRTCs)"); @@ -1718,13 +1453,8 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen, power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager); if (power_save_mode == META_POWER_SAVE_ON) { - FlipCrtcData data = { - .onscreen = onscreen, - .view = view, - .kms_update = kms_update, - }; - logical_monitor = meta_renderer_view_get_logical_monitor (view); - meta_logical_monitor_foreach_crtc (logical_monitor, flip_crtc, &data); + meta_onscreen_native_flip_crtc (onscreen, view, onscreen_native->crtc, + kms_update); } else { @@ -1738,13 +1468,10 @@ wait_for_pending_flips (CoglOnscreen *onscreen) CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; - GHashTableIter iter; GError *error = NULL; - g_hash_table_iter_init (&iter, onscreen_native->secondary_gpu_states); - while (g_hash_table_iter_next (&iter, - NULL, - (gpointer *) &secondary_gpu_state)) + secondary_gpu_state = onscreen_native->secondary_gpu_state; + if (secondary_gpu_state) { while (secondary_gpu_state->pending_flips) { @@ -2159,16 +1886,13 @@ update_secondary_gpu_state_pre_swap_buffers (CoglOnscreen *onscreen) { CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; - GHashTableIter iter; MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeGpuStatePreSwapBuffers, "Onscreen (secondary gpu pre-swap-buffers)"); - g_hash_table_iter_init (&iter, onscreen_native->secondary_gpu_states); - while (g_hash_table_iter_next (&iter, - NULL, - (gpointer *) &secondary_gpu_state)) + secondary_gpu_state = onscreen_native->secondary_gpu_state; + if (secondary_gpu_state) { MetaRendererNativeGpuData *renderer_gpu_data; @@ -2218,16 +1942,13 @@ update_secondary_gpu_state_post_swap_buffers (CoglOnscreen *onscreen, CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; MetaRendererNative *renderer_native = onscreen_native->renderer_native; - GHashTableIter iter; MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state; COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeGpuStatePostSwapBuffers, "Onscreen (secondary gpu post-swap-buffers)"); - g_hash_table_iter_init (&iter, onscreen_native->secondary_gpu_states); - while (g_hash_table_iter_next (&iter, - NULL, - (gpointer *) &secondary_gpu_state)) + secondary_gpu_state = onscreen_native->secondary_gpu_state; + if (secondary_gpu_state) { MetaRendererNativeGpuData *renderer_gpu_data; @@ -2343,9 +2064,9 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, if (onscreen_native->pending_set_crtc && power_save_mode == META_POWER_SAVE_ON) { - meta_onscreen_native_set_crtc_modes (onscreen, - renderer_gpu_data, - kms_update); + meta_onscreen_native_set_crtc_mode (onscreen, + renderer_gpu_data, + kms_update); onscreen_native->pending_set_crtc = FALSE; } @@ -2420,29 +2141,12 @@ should_surface_be_sharable (CoglOnscreen *onscreen) { CoglOnscreenEGL *onscreen_egl = onscreen->winsys; MetaOnscreenNative *onscreen_native = onscreen_egl->platform; - MetaRendererNative *renderer_native = onscreen_native->renderer_native; - CoglContext *cogl_context = COGL_FRAMEBUFFER (onscreen)->context; - CoglRenderer *cogl_renderer = cogl_context->display->renderer; - CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys; - MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform; - GList *l; - if (!onscreen_native->logical_monitor) + if (META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc)) == + onscreen_native->render_gpu) return FALSE; - - for (l = meta_logical_monitor_get_monitors (onscreen_native->logical_monitor); - l; - l = l->next) - { - MetaMonitor *monitor = l->data; - MetaGpuKms *gpu_kms = META_GPU_KMS (meta_monitor_get_gpu (monitor)); - - if (renderer_gpu_data != meta_renderer_native_get_gpu_data (renderer_native, - gpu_kms)) - return TRUE; - } - - return FALSE; + else + return TRUE; } static gboolean @@ -2532,15 +2236,16 @@ meta_renderer_native_create_surface_gbm (CoglOnscreen *onscreen, #ifdef HAVE_EGL_DEVICE static gboolean -meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen, - MetaLogicalMonitor *logical_monitor, - int width, - int height, - EGLStreamKHR *out_egl_stream, - EGLSurface *out_egl_surface, - GError **error) +meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen, + int width, + int height, + EGLStreamKHR *out_egl_stream, + EGLSurface *out_egl_surface, + GError **error) { CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglOnscreenEGL *onscreen_egl = onscreen->winsys; + MetaOnscreenNative *onscreen_native = onscreen_egl->platform; CoglContext *cogl_context = framebuffer->context; CoglDisplay *cogl_display = cogl_context->display; CoglDisplayEGL *cogl_display_egl = cogl_display->winsys; @@ -2550,9 +2255,6 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen, MetaEgl *egl = meta_renderer_native_get_egl (renderer_gpu_data->renderer_native); EGLDisplay egl_display = renderer_gpu_data->egl_display; - MetaMonitor *monitor; - MetaOutput *output; - MetaCrtc *crtc; EGLConfig egl_config; EGLStreamKHR egl_stream; EGLSurface egl_surface; @@ -2574,17 +2276,8 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen, if (egl_stream == EGL_NO_STREAM_KHR) return FALSE; - monitor = meta_logical_monitor_get_monitors (logical_monitor)->data; - output = meta_monitor_get_main_output (monitor); - crtc = meta_output_get_assigned_crtc (output); - - /* - * An "logical_monitor" may have multiple outputs/crtcs in case its tiled, - * but as far as I can tell, EGL only allows you to pass one crtc_id, so - * lets pass the first one. - */ output_attribs[0] = EGL_DRM_CRTC_EXT; - output_attribs[1] = crtc->crtc_id; + output_attribs[1] = onscreen_native->crtc->crtc_id; output_attribs[2] = EGL_NONE; if (!meta_egl_get_output_layers (egl, egl_display, @@ -2826,8 +2519,6 @@ meta_onscreen_native_allocate (CoglOnscreen *onscreen, int width; int height; #ifdef HAVE_EGL_DEVICE - MetaRendererView *view; - MetaLogicalMonitor *logical_monitor; EGLStreamKHR egl_stream; #endif @@ -2868,10 +2559,7 @@ meta_onscreen_native_allocate (CoglOnscreen *onscreen, error)) return FALSE; - view = onscreen_native->view; - logical_monitor = meta_renderer_view_get_logical_monitor (view); if (!meta_renderer_native_create_surface_egl_device (onscreen, - logical_monitor, width, height, &egl_stream, &egl_surface, @@ -2982,7 +2670,8 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen) #endif /* HAVE_EGL_DEVICE */ } - g_hash_table_destroy (onscreen_native->secondary_gpu_states); + g_clear_pointer (&onscreen_native->secondary_gpu_state, + secondary_gpu_state_free); g_slice_free (MetaOnscreenNative, onscreen_native); g_slice_free (CoglOnscreenEGL, onscreen->winsys); @@ -3052,29 +2741,16 @@ meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native) static CoglOnscreen * meta_renderer_native_create_onscreen (MetaRendererNative *renderer_native, MetaGpuKms *render_gpu, - MetaLogicalMonitor *logical_monitor, + MetaOutput *output, + MetaCrtc *crtc, CoglContext *context, - MetaMonitorTransform transform, - gint view_width, - gint view_height, + int width, + int height, GError **error) { CoglOnscreen *onscreen; CoglOnscreenEGL *onscreen_egl; MetaOnscreenNative *onscreen_native; - gint width, height; - GList *l; - - if (meta_monitor_transform_is_rotated (transform)) - { - width = view_height; - height = view_width; - } - else - { - width = view_width; - height = view_height; - } onscreen = cogl_onscreen_new (context, width, height); @@ -3088,24 +2764,12 @@ meta_renderer_native_create_onscreen (MetaRendererNative *renderer_native, onscreen_native = onscreen_egl->platform; onscreen_native->renderer_native = renderer_native; onscreen_native->render_gpu = render_gpu; - onscreen_native->logical_monitor = logical_monitor; - onscreen_native->secondary_gpu_states = - g_hash_table_new_full (NULL, NULL, - NULL, - (GDestroyNotify) secondary_gpu_state_free); + onscreen_native->output = output; + onscreen_native->crtc = crtc; - for (l = meta_logical_monitor_get_monitors (logical_monitor); l; l = l->next) + if (META_GPU_KMS (meta_crtc_get_gpu (crtc)) != render_gpu) { - MetaMonitor *monitor = l->data; - MetaGpuKms *gpu_kms = META_GPU_KMS (meta_monitor_get_gpu (monitor)); - - if (gpu_kms == render_gpu) - continue; - - if (get_secondary_gpu_state (onscreen, gpu_kms)) - continue; - - if (!init_secondary_gpu_state (renderer_native, onscreen, gpu_kms, error)) + if (!init_secondary_gpu_state (renderer_native, onscreen, error)) { cogl_object_unref (onscreen); return NULL; @@ -3225,24 +2889,15 @@ meta_onscreen_native_set_view (CoglOnscreen *onscreen, static MetaMonitorTransform calculate_view_transform (MetaMonitorManager *monitor_manager, - MetaLogicalMonitor *logical_monitor) + MetaLogicalMonitor *logical_monitor, + MetaOutput *output, + MetaCrtc *crtc) { - MetaMonitor *main_monitor; - MetaOutput *main_output; - MetaCrtc *crtc; MetaMonitorTransform crtc_transform; - main_monitor = meta_logical_monitor_get_monitors (logical_monitor)->data; - main_output = meta_monitor_get_main_output (main_monitor); - crtc = meta_output_get_assigned_crtc (main_output); + crtc = meta_output_get_assigned_crtc (output); crtc_transform = - meta_monitor_logical_to_crtc_transform (main_monitor, - logical_monitor->transform); - - /* - * Pick any monitor and output and check; all CRTCs of a logical monitor will - * always have the same transform assigned to them. - */ + meta_output_logical_to_crtc_transform (output, logical_monitor->transform); if (meta_monitor_manager_is_transform_handled (monitor_manager, crtc, @@ -3295,7 +2950,9 @@ should_force_shadow_fb (MetaRendererNative *renderer_native, static MetaRendererView * meta_renderer_native_create_view (MetaRenderer *renderer, - MetaLogicalMonitor *logical_monitor) + MetaLogicalMonitor *logical_monitor, + MetaOutput *output, + MetaCrtc *crtc) { MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); MetaBackend *backend = meta_renderer_get_backend (renderer); @@ -3306,42 +2963,56 @@ meta_renderer_native_create_view (MetaRenderer *renderer, CoglDisplay *cogl_display = cogl_context_get_display (cogl_context); CoglDisplayEGL *cogl_display_egl; CoglOnscreenEGL *onscreen_egl; + MetaCrtcConfig *crtc_config; MetaMonitorTransform view_transform; CoglOnscreen *onscreen = NULL; CoglOffscreen *offscreen = NULL; CoglOffscreen *shadowfb = NULL; float scale; - int width, height; + int onscreen_width; + int onscreen_height; MetaRendererView *view; GError *error = NULL; - view_transform = calculate_view_transform (monitor_manager, logical_monitor); - - if (meta_is_stage_views_scaled ()) - scale = meta_logical_monitor_get_scale (logical_monitor); - else - scale = 1.0; - - width = roundf (logical_monitor->rect.width * scale); - height = roundf (logical_monitor->rect.height * scale); + crtc_config = crtc->config; + onscreen_width = crtc_config->mode->width; + onscreen_height = crtc_config->mode->height; onscreen = meta_renderer_native_create_onscreen (renderer_native, renderer_native->primary_gpu_kms, - logical_monitor, + output, + crtc, cogl_context, - view_transform, - width, - height, + onscreen_width, + onscreen_height, &error); if (!onscreen) g_error ("Failed to allocate onscreen framebuffer: %s", error->message); + view_transform = calculate_view_transform (monitor_manager, + logical_monitor, + output, + crtc); if (view_transform != META_MONITOR_TRANSFORM_NORMAL) { + int offscreen_width; + int offscreen_height; + + if (meta_monitor_transform_is_rotated (view_transform)) + { + offscreen_width = onscreen_height; + offscreen_height = onscreen_width; + } + else + { + offscreen_width = onscreen_width; + offscreen_height = onscreen_height; + } + offscreen = meta_renderer_native_create_offscreen (renderer_native, cogl_context, - width, - height, + offscreen_width, + offscreen_height, &error); if (!offscreen) g_error ("Failed to allocate back buffer texture: %s", error->message); @@ -3366,13 +3037,17 @@ meta_renderer_native_create_view (MetaRenderer *renderer, g_error ("Failed to allocate shadow buffer texture: %s", error->message); } + if (meta_is_stage_views_scaled ()) + scale = meta_logical_monitor_get_scale (logical_monitor); + else + scale = 1.0; + view = g_object_new (META_TYPE_RENDERER_VIEW, "layout", &logical_monitor->rect, "scale", scale, "framebuffer", onscreen, "offscreen", offscreen, "shadowfb", shadowfb, - "logical-monitor", logical_monitor, "transform", view_transform, NULL); g_clear_pointer (&offscreen, cogl_object_unref); diff --git a/src/backends/x11/nested/meta-renderer-x11-nested.c b/src/backends/x11/nested/meta-renderer-x11-nested.c index caf80fc2b..6c8b9d63f 100644 --- a/src/backends/x11/nested/meta-renderer-x11-nested.c +++ b/src/backends/x11/nested/meta-renderer-x11-nested.c @@ -172,7 +172,9 @@ meta_renderer_x11_nested_ensure_legacy_view (MetaRendererX11Nested *renderer_x11 static MetaRendererView * meta_renderer_x11_nested_create_view (MetaRenderer *renderer, - MetaLogicalMonitor *logical_monitor) + MetaLogicalMonitor *logical_monitor, + MetaOutput *output, + MetaCrtc *crtc) { MetaBackend *backend = meta_get_backend (); MetaMonitorManager *monitor_manager = @@ -184,6 +186,8 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer, int width, height; CoglOffscreen *fake_onscreen; CoglOffscreen *offscreen; + MetaRectangle view_layout; + MetaRendererView *view; view_transform = calculate_view_transform (monitor_manager, logical_monitor); @@ -192,18 +196,8 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer, else view_scale = 1.0; - if (meta_monitor_transform_is_rotated (view_transform)) - { - width = logical_monitor->rect.height; - height = logical_monitor->rect.width; - } - else - { - width = logical_monitor->rect.width; - height = logical_monitor->rect.height; - } - width = roundf (width * view_scale); - height = roundf (height * view_scale); + width = roundf (crtc->config->layout.size.width * view_scale); + height = roundf (crtc->config->layout.size.height * view_scale); fake_onscreen = create_offscreen (cogl_context, width, height); @@ -212,14 +206,20 @@ meta_renderer_x11_nested_create_view (MetaRenderer *renderer, else offscreen = NULL; - return g_object_new (META_TYPE_RENDERER_VIEW, - "layout", &logical_monitor->rect, + meta_rectangle_from_graphene_rect (&crtc->config->layout, + META_ROUNDING_STRATEGY_ROUND, + &view_layout); + + view = g_object_new (META_TYPE_RENDERER_VIEW, + "layout", &view_layout, "framebuffer", COGL_FRAMEBUFFER (fake_onscreen), "offscreen", COGL_FRAMEBUFFER (offscreen), "transform", view_transform, "scale", view_scale, - "logical-monitor", logical_monitor, NULL); + g_object_set_data (G_OBJECT (view), "crtc", crtc); + + return view; } static void diff --git a/src/backends/x11/nested/meta-stage-x11-nested.c b/src/backends/x11/nested/meta-stage-x11-nested.c index a9704e1f5..361f905ed 100644 --- a/src/backends/x11/nested/meta-stage-x11-nested.c +++ b/src/backends/x11/nested/meta-stage-x11-nested.c @@ -101,46 +101,33 @@ typedef struct } DrawCrtcData; static gboolean -draw_crtc (MetaMonitor *monitor, - MetaMonitorMode *monitor_mode, - MetaMonitorCrtcMode *monitor_crtc_mode, - gpointer user_data, - GError **error) +draw_view (MetaStageX11Nested *stage_nested, + MetaRendererView *renderer_view, + CoglTexture *texture) { - DrawCrtcData *data = user_data; - MetaStageX11 *stage_x11 = META_STAGE_X11 (data->stage_nested); + MetaStageX11 *stage_x11 = META_STAGE_X11 (stage_nested); CoglFramebuffer *onscreen = COGL_FRAMEBUFFER (stage_x11->onscreen); - CoglTexture *texture = data->texture; - MetaLogicalMonitor *logical_monitor = data->logical_monitor; - MetaOutput *output = monitor_crtc_mode->output; + ClutterStageView *stage_view = CLUTTER_STAGE_VIEW (renderer_view); MetaCrtc *crtc; MetaCrtcConfig *crtc_config; - MetaRendererView *renderer_view = META_RENDERER_VIEW (data->view); - MetaMonitorTransform view_transform; - MetaMonitorTransform layout_transform = META_MONITOR_TRANSFORM_NORMAL; - cairo_rectangle_int_t view_layout; CoglMatrix projection_matrix; CoglMatrix transform; float texture_width, texture_height; float sample_x, sample_y, sample_width, sample_height; - float scale; - int viewport_x, viewport_y; - int viewport_width, viewport_height; float s_1, t_1, s_2, t_2; texture_width = cogl_texture_get_width (texture); texture_height = cogl_texture_get_height (texture); - crtc = meta_output_get_assigned_crtc (output); + crtc = g_object_get_data (G_OBJECT (renderer_view), "crtc"); crtc_config = crtc->config; - clutter_stage_view_get_layout (data->view, &view_layout); - sample_x = (int) roundf (crtc_config->layout.origin.x) - view_layout.x; - sample_y = (int) roundf (crtc_config->layout.origin.y) - view_layout.y; - sample_width = (int) roundf (crtc_config->layout.size.width); - sample_height = (int) roundf (crtc_config->layout.size.height); + sample_x = 0; + sample_y = 0; + sample_width = texture_width; + sample_height = texture_height; - clutter_stage_view_get_offscreen_transformation_matrix (data->view, + clutter_stage_view_get_offscreen_transformation_matrix (stage_view, &transform); cogl_framebuffer_push_matrix (onscreen); @@ -156,62 +143,14 @@ draw_crtc (MetaMonitor *monitor, s_2 = (sample_x + sample_width) / texture_width; t_2 = (sample_y + sample_height) / texture_height; - view_transform = meta_renderer_view_get_transform (renderer_view); - - if (view_transform == logical_monitor->transform) - { - switch (view_transform) - { - case META_MONITOR_TRANSFORM_NORMAL: - case META_MONITOR_TRANSFORM_FLIPPED: - layout_transform = META_MONITOR_TRANSFORM_NORMAL; - break; - case META_MONITOR_TRANSFORM_270: - case META_MONITOR_TRANSFORM_FLIPPED_270: - layout_transform = META_MONITOR_TRANSFORM_90; - break; - case META_MONITOR_TRANSFORM_180: - case META_MONITOR_TRANSFORM_FLIPPED_180: - layout_transform = META_MONITOR_TRANSFORM_180; - break; - case META_MONITOR_TRANSFORM_90: - case META_MONITOR_TRANSFORM_FLIPPED_90: - layout_transform = META_MONITOR_TRANSFORM_270; - break; - } - } - else - { - layout_transform = logical_monitor->transform; - } - - meta_monitor_calculate_crtc_pos (monitor, monitor_mode, output, - layout_transform, - &viewport_x, - &viewport_y); - viewport_x += logical_monitor->rect.x; - viewport_y += logical_monitor->rect.y; - if (meta_monitor_transform_is_rotated (logical_monitor->transform)) - { - viewport_width = monitor_crtc_mode->crtc_mode->height; - viewport_height = monitor_crtc_mode->crtc_mode->width; - } - else - { - viewport_width = monitor_crtc_mode->crtc_mode->width; - viewport_height = monitor_crtc_mode->crtc_mode->height; - } - - scale = clutter_stage_view_get_scale (data->view); - viewport_width = roundf (viewport_width / scale); - viewport_height = roundf (viewport_height / scale); - cogl_framebuffer_set_viewport (onscreen, - viewport_x, viewport_y, - viewport_width, viewport_height); + crtc_config->layout.origin.x, + crtc_config->layout.origin.y, + crtc_config->layout.size.width, + crtc_config->layout.size.height); cogl_framebuffer_draw_textured_rectangle (onscreen, - data->stage_nested->pipeline, + stage_nested->pipeline, 0, 0, 1, 1, s_1, t_1, s_2, t_2); @@ -219,32 +158,6 @@ draw_crtc (MetaMonitor *monitor, return TRUE; } -static void -draw_logical_monitor (MetaStageX11Nested *stage_nested, - MetaLogicalMonitor *logical_monitor, - CoglTexture *texture, - ClutterStageView *view, - cairo_rectangle_int_t *view_layout) -{ - MetaMonitor *monitor; - MetaMonitorMode *current_mode; - - cogl_pipeline_set_layer_wrap_mode (stage_nested->pipeline, 0, - COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - - monitor = meta_logical_monitor_get_monitors (logical_monitor)->data; - current_mode = meta_monitor_get_current_mode (monitor); - meta_monitor_mode_foreach_crtc (monitor, current_mode, - draw_crtc, - &(DrawCrtcData) { - .stage_nested = stage_nested, - .texture = texture, - .view = view, - .logical_monitor = logical_monitor - }, - NULL); -} - static void meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window) { @@ -267,39 +180,17 @@ meta_stage_x11_nested_finish_frame (ClutterStageWindow *stage_window) { ClutterStageView *view = l->data; MetaRendererView *renderer_view = META_RENDERER_VIEW (view); - MetaLogicalMonitor *logical_monitor; - cairo_rectangle_int_t view_layout; CoglFramebuffer *framebuffer; CoglTexture *texture; - clutter_stage_view_get_layout (view, &view_layout); - framebuffer = clutter_stage_view_get_onscreen (view); texture = cogl_offscreen_get_texture (COGL_OFFSCREEN (framebuffer)); cogl_pipeline_set_layer_texture (stage_nested->pipeline, 0, texture); + cogl_pipeline_set_layer_wrap_mode (stage_nested->pipeline, 0, + COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE); - logical_monitor = meta_renderer_view_get_logical_monitor (renderer_view); - if (logical_monitor) - { - draw_logical_monitor (stage_nested, logical_monitor, texture, view, &view_layout); - } - else - { - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); - GList *logical_monitors; - GList *k; - - logical_monitors = - meta_monitor_manager_get_logical_monitors (monitor_manager); - for (k = logical_monitors; k; k = k->next) - { - logical_monitor = k->data; - - draw_logical_monitor (stage_nested, logical_monitor, texture, view, &view_layout); - } - } + draw_view (stage_nested, renderer_view, texture); } cogl_onscreen_swap_buffers (stage_x11->onscreen);