diff --git a/src/backends/meta-screen-cast-stream-src.c b/src/backends/meta-screen-cast-stream-src.c index 98e69a64a..f5cf3c251 100644 --- a/src/backends/meta-screen-cast-stream-src.c +++ b/src/backends/meta-screen-cast-stream-src.c @@ -111,6 +111,8 @@ typedef struct _MetaScreenCastStreamSrcPrivate GHashTable *dmabuf_handles; MtkRegion *redraw_clip; + + GHashTable *modifiers; } MetaScreenCastStreamSrcPrivate; static const struct { @@ -164,6 +166,7 @@ push_format_object (struct spa_pod_builder *pod_builder, enum spa_video_format format, uint64_t *modifiers, int n_modifiers, + gboolean fixate_modifier, ...) { struct spa_pod_frame pod_frames[2]; @@ -182,33 +185,34 @@ push_format_object (struct spa_pod_builder *pod_builder, spa_pod_builder_add (pod_builder, SPA_FORMAT_VIDEO_format, SPA_POD_Id (format), 0); -#ifdef HAVE_NATIVE_BACKEND - if (n_modifiers == 1 && modifiers[0] == DRM_FORMAT_MOD_INVALID) + if (n_modifiers > 0) { - spa_pod_builder_prop (pod_builder, - SPA_FORMAT_VIDEO_modifier, - SPA_POD_PROP_FLAG_MANDATORY); - spa_pod_builder_long (pod_builder, modifiers[0]); - } - else if (n_modifiers > 0) - { - int i; + if (fixate_modifier) + { + spa_pod_builder_prop (pod_builder, + SPA_FORMAT_VIDEO_modifier, + SPA_POD_PROP_FLAG_MANDATORY); + spa_pod_builder_long (pod_builder, modifiers[0]); + } + else + { + int i; - spa_pod_builder_prop (pod_builder, - SPA_FORMAT_VIDEO_modifier, - (SPA_POD_PROP_FLAG_MANDATORY | - SPA_POD_PROP_FLAG_DONT_FIXATE)); - spa_pod_builder_push_choice (pod_builder, &pod_frames[1], - SPA_CHOICE_Enum, - 0); - spa_pod_builder_long (pod_builder, modifiers[0]); - for (i = 0; i < n_modifiers; i++) - spa_pod_builder_long (pod_builder, modifiers[i]); - spa_pod_builder_pop (pod_builder, &pod_frames[1]); + spa_pod_builder_prop (pod_builder, + SPA_FORMAT_VIDEO_modifier, + (SPA_POD_PROP_FLAG_MANDATORY | + SPA_POD_PROP_FLAG_DONT_FIXATE)); + spa_pod_builder_push_choice (pod_builder, &pod_frames[1], + SPA_CHOICE_Enum, + 0); + spa_pod_builder_long (pod_builder, modifiers[0]); + for (i = 0; i < n_modifiers; i++) + spa_pod_builder_long (pod_builder, modifiers[i]); + spa_pod_builder_pop (pod_builder, &pod_frames[1]); + } } -#endif /* HAVE_NATIVE_BACKEND */ - va_start (args, n_modifiers); + va_start (args, fixate_modifier); spa_pod_builder_addv (pod_builder, args); va_end (args); return spa_pod_builder_pop (pod_builder, &pod_frames[0]); @@ -967,17 +971,21 @@ meta_screen_cast_stream_src_close (MetaScreenCastStreamSrc *src) priv->emit_closed_after_dispatch = TRUE; } -static uint32_t -build_format_params (MetaScreenCastStreamSrc *src, - struct spa_pod_builder *pod_builder, - const struct spa_pod *params[4]) +static void +build_format_params (MetaScreenCastStreamSrc *src, + struct spa_pod_builder *pod_builder, + const struct spa_pod **params, + uint32_t *n_params) { - MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); - MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream); + MetaScreenCastStream *stream = + meta_screen_cast_stream_src_get_stream (src); + MetaScreenCastSession *session = + meta_screen_cast_stream_get_session (stream); + MetaScreenCastStreamSrcPrivate *priv = + meta_screen_cast_stream_src_get_instance_private (src); MetaScreenCast *screen_cast = meta_screen_cast_session_get_screen_cast (session); - uint64_t *modifiers; - int n_modifiers; + GArray *modifiers; CoglPixelFormat preferred_cogl_format = meta_screen_cast_stream_src_get_preferred_format (src); enum spa_video_format preferred_spa_video_format; @@ -989,7 +997,6 @@ build_format_params (MetaScreenCastStreamSrc *src, struct spa_fraction default_framerate = DEFAULT_FRAME_RATE; struct spa_fraction min_framerate = MIN_FRAME_RATE; struct spa_fraction max_framerate = MAX_FRAME_RATE; - uint32_t n_params = 0; int width; int height; float frame_rate; @@ -1026,28 +1033,36 @@ build_format_params (MetaScreenCastStreamSrc *src, if (!cogl_pixel_format_from_spa_video_format (spa_video_formats[i], &cogl_format)) continue; - if (meta_screen_cast_query_modifiers (screen_cast, cogl_format, &modifiers, &n_modifiers)) + modifiers = g_hash_table_lookup (priv->modifiers, + GINT_TO_POINTER (cogl_format)); + if (modifiers == NULL) { - params[n_params++] = push_format_object ( - pod_builder, - spa_video_formats[i], modifiers, n_modifiers, - SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle (&default_size, - &min_size, - &max_size), - SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction (&SPA_FRACTION (0, 1)), - SPA_FORMAT_VIDEO_maxFramerate, - SPA_POD_CHOICE_RANGE_Fraction (&default_framerate, - &min_framerate, - &max_framerate), - 0); - free (modifiers); + modifiers = meta_screen_cast_query_modifiers (screen_cast, cogl_format); + g_hash_table_insert (priv->modifiers, + GINT_TO_POINTER (cogl_format), + modifiers); } - } - for (i = 0; i < n_spa_video_formats; i++) - { - params[n_params++] = push_format_object ( + if (modifiers->len == 0) + continue; + + params[(*n_params)++] = push_format_object ( pod_builder, - spa_video_formats[i], NULL, 0, + spa_video_formats[i], (uint64_t *) modifiers->data, modifiers->len, FALSE, + SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle (&default_size, + &min_size, + &max_size), + SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction (&SPA_FRACTION (0, 1)), + SPA_FORMAT_VIDEO_maxFramerate, + SPA_POD_CHOICE_RANGE_Fraction (&default_framerate, + &min_framerate, + &max_framerate), + 0); + } + for (i = 0; i < n_spa_video_formats; i++) + { + params[(*n_params)++] = push_format_object ( + pod_builder, + spa_video_formats[i], NULL, 0, FALSE, SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle (&default_size, &min_size, &max_size), @@ -1058,8 +1073,6 @@ build_format_params (MetaScreenCastStreamSrc *src, &max_framerate), 0); } - - return n_params; } static void @@ -1070,10 +1083,10 @@ renegotiate_pipewire_stream (MetaScreenCastStreamSrc *src) uint8_t buffer[1024]; struct spa_pod_builder pod_builder; const struct spa_pod *params[4]; - int n_params; + uint32_t n_params = 0; pod_builder = SPA_POD_BUILDER_INIT (buffer, sizeof (buffer)); - n_params = build_format_params (src, &pod_builder, params); + build_format_params (src, &pod_builder, params, &n_params); pw_stream_update_params (priv->pipewire_stream, params, n_params); } @@ -1147,8 +1160,9 @@ on_stream_param_changed (void *data, uint8_t params_buffer[1024]; struct spa_pod_builder pod_builder; const struct spa_pod *params[5]; - int n_params = 0; + uint32_t n_params = 0; int buffer_types; + const struct spa_pod_prop *prop_modifier; if (!format || id != SPA_PARAM_Format) return; @@ -1157,12 +1171,82 @@ on_stream_param_changed (void *data, &priv->video_format); pod_builder = SPA_POD_BUILDER_INIT (params_buffer, sizeof (params_buffer)); + prop_modifier = spa_pod_find_prop (format, NULL, SPA_FORMAT_VIDEO_modifier); - if (spa_pod_find_prop (format, NULL, SPA_FORMAT_VIDEO_modifier)) + if (prop_modifier) buffer_types = 1 << SPA_DATA_DmaBuf; else buffer_types = 1 << SPA_DATA_MemFd; + if (prop_modifier && (prop_modifier->flags & SPA_POD_PROP_FLAG_DONT_FIXATE)) + { + MetaScreenCastStream *stream = + meta_screen_cast_stream_src_get_stream (src); + MetaScreenCastSession *session = + meta_screen_cast_stream_get_session (stream); + MetaScreenCast *screen_cast = + meta_screen_cast_session_get_screen_cast (session); + CoglPixelFormat cogl_format; + const struct spa_pod *pod_modifier = &prop_modifier->value; + uint64_t *negotiated_modifiers = SPA_POD_CHOICE_VALUES (pod_modifier); + uint32_t n_negotiated_modifiers = SPA_POD_CHOICE_N_VALUES (pod_modifier); + GArray *supported_modifiers; + uint64_t preferred_modifier; + int i; + + if (!cogl_pixel_format_from_spa_video_format (priv->video_format.format, + &cogl_format)) + g_assert_not_reached (); + + supported_modifiers = g_hash_table_lookup (priv->modifiers, + GINT_TO_POINTER (cogl_format)); + g_array_set_size (supported_modifiers, 0); + for (i = 0; i < n_negotiated_modifiers; i++) + { + uint64_t modifier = negotiated_modifiers[i]; + gboolean found = FALSE; + int j; + + for (j = 0; j < supported_modifiers->len; j++) + { + if (g_array_index (supported_modifiers, uint64_t, j) == modifier) + { + found = TRUE; + break; + } + } + + if (!found) + g_array_append_vals (supported_modifiers, &modifier, 1); + } + + if (meta_screen_cast_get_preferred_modifier (screen_cast, + cogl_format, + supported_modifiers, + priv->video_format.size.width, + priv->video_format.size.height, + &preferred_modifier)) + { + params[n_params++] = push_format_object ( + &pod_builder, + priv->video_format.format, &preferred_modifier, 1, TRUE, + SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle (&priv->video_format.size, + &priv->video_format.size, + &priv->video_format.size), + SPA_FORMAT_VIDEO_framerate, SPA_POD_Fraction (&SPA_FRACTION (0, 1)), + SPA_FORMAT_VIDEO_maxFramerate, + SPA_POD_CHOICE_RANGE_Fraction (&priv->video_format.max_framerate, + &MIN_FRAME_RATE, + &priv->video_format.max_framerate), + 0); + } + + build_format_params (src, &pod_builder, params, &n_params); + + pw_stream_update_params (priv->pipewire_stream, params, n_params); + return; + } + params[n_params++] = spa_pod_builder_add_object ( &pod_builder, SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers, @@ -1204,10 +1288,6 @@ on_stream_add_buffer (void *data, MetaScreenCastStreamSrc *src = data; MetaScreenCastStreamSrcPrivate *priv = meta_screen_cast_stream_src_get_instance_private (src); - MetaScreenCastStream *stream = meta_screen_cast_stream_src_get_stream (src); - MetaScreenCastSession *session = meta_screen_cast_stream_get_session (stream); - MetaScreenCast *screen_cast = - meta_screen_cast_session_get_screen_cast (session); CoglDmaBufHandle *dmabuf_handle; struct spa_buffer *spa_buffer = buffer->buffer; struct spa_data *spa_data = &spa_buffer->datas[0]; @@ -1220,6 +1300,12 @@ on_stream_add_buffer (void *data, if (spa_data->type & (1 << SPA_DATA_DmaBuf)) { + MetaScreenCastStream *stream = + meta_screen_cast_stream_src_get_stream (src); + MetaScreenCastSession *session = + meta_screen_cast_stream_get_session (stream); + MetaScreenCast *screen_cast = + meta_screen_cast_session_get_screen_cast (session); CoglPixelFormat cogl_format; if (!cogl_pixel_format_from_spa_video_format (priv->video_format.format, @@ -1229,13 +1315,26 @@ on_stream_add_buffer (void *data, dmabuf_handle = meta_screen_cast_create_dma_buf_handle (screen_cast, cogl_format, + priv->video_format.modifier, priv->video_format.size.width, priv->video_format.size.height); if (!dmabuf_handle) { - // TODO: Drop dmabuf support more granular - meta_screen_cast_disable_dma_bufs (screen_cast); - renegotiate_pipewire_stream (src); + GArray *modifiers; + int i; + + modifiers = g_hash_table_lookup (priv->modifiers, + GINT_TO_POINTER (cogl_format)); + for (i = 0; i < modifiers->len; i++) + { + if (g_array_index (modifiers, uint64_t, i) == priv->video_format.modifier) + { + g_array_remove_index (modifiers, i); + renegotiate_pipewire_stream (src); + break; + } + } + return; } @@ -1369,7 +1468,7 @@ create_pipewire_stream (MetaScreenCastStreamSrc *src, struct spa_pod_builder pod_builder = SPA_POD_BUILDER_INIT (buffer, sizeof (buffer)); const struct spa_pod *params[4]; - int n_params = 0; + uint32_t n_params = 0; int result; priv->node_id = SPA_ID_INVALID; @@ -1385,7 +1484,7 @@ create_pipewire_stream (MetaScreenCastStreamSrc *src, return NULL; } - n_params = build_format_params (src, &pod_builder, params); + build_format_params (src, &pod_builder, params, &n_params); pw_stream_add_listener (pipewire_stream, &priv->pipewire_stream_listener, @@ -1581,10 +1680,18 @@ meta_screen_cast_stream_src_dispose (GObject *object) MetaScreenCastStreamSrc *src = META_SCREEN_CAST_STREAM_SRC (object); MetaScreenCastStreamSrcPrivate *priv = meta_screen_cast_stream_src_get_instance_private (src); + GHashTableIter modifierIter; + gpointer key, value; if (meta_screen_cast_stream_src_is_enabled (src)) meta_screen_cast_stream_src_disable (src); + g_hash_table_iter_init (&modifierIter, + priv->modifiers); + while (g_hash_table_iter_next (&modifierIter, &key, &value)) + g_array_free (value, TRUE); + + g_clear_pointer (&priv->modifiers, g_hash_table_destroy); g_clear_pointer (&priv->pipewire_stream, pw_stream_destroy); g_clear_pointer (&priv->dmabuf_handles, g_hash_table_destroy); g_clear_pointer (&priv->pipewire_core, pw_core_disconnect); @@ -1643,6 +1750,8 @@ meta_screen_cast_stream_src_init (MetaScreenCastStreamSrc *src) priv->dmabuf_handles = g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) cogl_dma_buf_handle_free); + + priv->modifiers = g_hash_table_new (NULL, NULL); } static void diff --git a/src/backends/meta-screen-cast.c b/src/backends/meta-screen-cast.c index 8be4fa4dd..ea5bf147c 100644 --- a/src/backends/meta-screen-cast.c +++ b/src/backends/meta-screen-cast.c @@ -24,14 +24,20 @@ #include -#ifdef HAVE_NATIVE_BACKEND -#include -#endif - #include "backends/meta-backend-private.h" #include "backends/meta-remote-desktop-session.h" #include "backends/meta-screen-cast-session.h" +#ifdef HAVE_NATIVE_BACKEND +#include "backends/native/meta-drm-buffer.h" +#include "backends/native/meta-render-device.h" +#include "backends/native/meta-renderer-native-private.h" + +#include "cogl/cogl-egl.h" + +#include "common/meta-cogl-drm-formats.h" +#endif + #define META_SCREEN_CAST_DBUS_SERVICE "org.gnome.Mutter.ScreenCast" #define META_SCREEN_CAST_DBUS_PATH "/org/gnome/Mutter/ScreenCast" #define META_SCREEN_CAST_API_VERSION 4 @@ -39,8 +45,6 @@ struct _MetaScreenCast { MetaDbusSessionManager parent; - - gboolean disable_dma_bufs; }; G_DEFINE_TYPE (MetaScreenCast, meta_screen_cast, @@ -54,68 +58,228 @@ meta_screen_cast_get_backend (MetaScreenCast *screen_cast) return meta_dbus_session_manager_get_backend (session_manager); } -void -meta_screen_cast_disable_dma_bufs (MetaScreenCast *screen_cast) +gboolean +meta_screen_cast_get_preferred_modifier (MetaScreenCast *screen_cast, + CoglPixelFormat format, + GArray *modifiers, + int width, + int height, + uint64_t *preferred_modifier) { - screen_cast->disable_dma_bufs = TRUE; -} - -bool -meta_screen_cast_query_modifiers (MetaScreenCast *screen_cast, - CoglPixelFormat format, - uint64_t **modifiers, - int *n_modifiers) -{ - MetaDbusSessionManager *session_manager = - META_DBUS_SESSION_MANAGER (screen_cast); +#ifdef HAVE_NATIVE_BACKEND MetaBackend *backend = - meta_dbus_session_manager_get_backend (session_manager); + meta_screen_cast_get_backend (screen_cast); ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); - CoglRenderer *cogl_renderer = cogl_context_get_renderer (cogl_context); + CoglRenderer *cogl_renderer = + cogl_context_get_renderer (cogl_context); + CoglRendererEGL *cogl_renderer_egl = + cogl_renderer->winsys; + MetaRendererNativeGpuData *renderer_gpu_data = + cogl_renderer_egl->platform; + MetaRenderDevice *render_device = + renderer_gpu_data->render_device; + MetaRendererNative *renderer_native = + renderer_gpu_data->renderer_native; + int dmabuf_fd; + uint32_t stride; + uint32_t offset; g_autoptr (GError) error = NULL; - bool ret; + const MetaFormatInfo *format_info; + gboolean use_implicit_modifier; - if (screen_cast->disable_dma_bufs) - return FALSE; + g_assert (cogl_renderer_is_dma_buf_supported (cogl_renderer)); + + format_info = meta_format_info_from_cogl_format (format); + g_assert (format_info); + + while (modifiers->len > 0) + { + g_autoptr (MetaDrmBuffer) dmabuf = NULL; + g_autoptr (CoglFramebuffer) fb = NULL; + + if ((modifiers->len > 1) || + (g_array_index (modifiers, uint64_t, 0) != DRM_FORMAT_MOD_INVALID)) + use_implicit_modifier = FALSE; + else + use_implicit_modifier = TRUE; + + dmabuf = meta_render_device_allocate_dma_buf (render_device, + width, height, + format_info->drm_format, + (uint64_t *) modifiers->data, + use_implicit_modifier ? 0 : modifiers->len, + META_DRM_BUFFER_FLAG_NONE, + &error); + if (!dmabuf) + break; + + stride = meta_drm_buffer_get_stride (dmabuf); + offset = meta_drm_buffer_get_offset (dmabuf, 0); + + dmabuf_fd = meta_drm_buffer_export_fd (dmabuf, &error); + if (dmabuf_fd == -1) + break; + + if (use_implicit_modifier) + { + *preferred_modifier = DRM_FORMAT_MOD_INVALID; + fb = meta_renderer_native_create_dma_buf_framebuffer (renderer_native, + dmabuf_fd, + width, height, + stride, + offset, + NULL, + format_info->drm_format, + &error); + } + else + { + *preferred_modifier = meta_drm_buffer_get_modifier (dmabuf); + fb = meta_renderer_native_create_dma_buf_framebuffer (renderer_native, + dmabuf_fd, + width, height, + stride, + offset, + preferred_modifier, + format_info->drm_format, + &error); + } + close (dmabuf_fd); + + if (!fb) + { + int i; + + for (i = 0; i < modifiers->len; i++) + { + if (g_array_index (modifiers, uint64_t, i) == *preferred_modifier) + { + g_array_remove_index (modifiers, i); + break; + } + } + } + else + { + return TRUE; + } + } +#endif + + g_array_set_size (modifiers, 0); + return FALSE; +} + +GArray * +meta_screen_cast_query_modifiers (MetaScreenCast *screen_cast, + CoglPixelFormat format) +{ +#ifdef HAVE_NATIVE_BACKEND + MetaBackend *backend = + meta_screen_cast_get_backend (screen_cast); + ClutterBackend *clutter_backend = + meta_backend_get_clutter_backend (backend); + CoglContext *cogl_context = + clutter_backend_get_cogl_context (clutter_backend); + CoglRenderer *cogl_renderer = + cogl_context_get_renderer (cogl_context); + EGLDisplay egl_display = + cogl_egl_context_get_egl_display (cogl_context); + MetaEgl *egl = + meta_backend_get_egl (backend); + EGLint num_modifiers; + g_autofree EGLuint64KHR *all_modifiers = NULL; + g_autofree EGLBoolean *external_only = NULL; + g_autoptr (GError) error = NULL; + g_autoptr (CoglDmaBufHandle) dmabuf_handle = NULL; + GArray *modifiers = NULL; + gboolean ret; + const MetaFormatInfo *format_info; + uint64_t modifier; + int i; if (!cogl_renderer_is_dma_buf_supported (cogl_renderer)) - return FALSE; + return g_array_new (FALSE, FALSE, sizeof (uint64_t)); + + format_info = meta_format_info_from_cogl_format (format); + g_assert (format_info); // TODO: query cogl_renderer for modifiers // BEGIN stub -#ifdef HAVE_NATIVE_BACKEND - uint64_t *modifier_list; + ret = meta_egl_query_dma_buf_modifiers (egl, + egl_display, + format_info->drm_format, + 0, + NULL, + NULL, + &num_modifiers, + &error); + if (!ret || num_modifiers == 0) + { + if (error) + g_warning ("Failed to query DMA-BUF modifiers: %s", error->message); + goto add_implicit_modifier; + } - modifier_list = calloc (1, sizeof (uint64_t)); - modifier_list[0] = DRM_FORMAT_MOD_INVALID; + all_modifiers = g_new (uint64_t, num_modifiers); + external_only = g_new (EGLBoolean, num_modifiers); - *modifiers = modifier_list; - *n_modifiers = 1; - ret = TRUE; -#else - ret = FALSE; -#endif + ret = meta_egl_query_dma_buf_modifiers (egl, + egl_display, + format_info->drm_format, + num_modifiers, + all_modifiers, + external_only, + &num_modifiers, + &error); + if (!ret) + { + g_warning ("Failed to query DMA-BUF modifiers: %s", error->message); + goto add_implicit_modifier; + } + + modifiers = g_array_sized_new (FALSE, FALSE, sizeof (uint64_t), + num_modifiers + 1); + + for (i = 0; i < num_modifiers; i++) + { + if (!external_only[i]) + { + modifier = all_modifiers[i]; + g_array_append_vals (modifiers, &modifier, 1); + } + } // END stub - if (!ret) - g_warning ("Failed to query supported modifiers: %s", - error->message); - return ret; +add_implicit_modifier: + if (!modifiers) + { + g_warning ("Couldn't retrieve the supported modifiers"); + modifiers = g_array_new (FALSE, FALSE, sizeof (uint64_t)); + } + + modifier = DRM_FORMAT_MOD_INVALID; + g_array_append_vals (modifiers, &modifier, 1); + + return modifiers; +#else + return g_array_new (FALSE, FALSE, sizeof (uint64_t)); +#endif } CoglDmaBufHandle * meta_screen_cast_create_dma_buf_handle (MetaScreenCast *screen_cast, CoglPixelFormat format, + uint64_t modifier, int width, int height) { - MetaDbusSessionManager *session_manager = - META_DBUS_SESSION_MANAGER (screen_cast); +#ifdef HAVE_NATIVE_BACKEND MetaBackend *backend = - meta_dbus_session_manager_get_backend (session_manager); + meta_screen_cast_get_backend (screen_cast); ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); CoglContext *cogl_context = @@ -123,25 +287,20 @@ meta_screen_cast_create_dma_buf_handle (MetaScreenCast *screen_cast, CoglRenderer *cogl_renderer = cogl_context_get_renderer (cogl_context); g_autoptr (GError) error = NULL; CoglDmaBufHandle *dmabuf_handle; + int n_modifiers; - if (screen_cast->disable_dma_bufs) - return NULL; + n_modifiers = (modifier == DRM_FORMAT_MOD_INVALID) ? 0 + : 1; dmabuf_handle = cogl_renderer_create_dma_buf (cogl_renderer, format, - NULL, 0, + &modifier, n_modifiers, width, height, &error); - if (!dmabuf_handle) - { - g_warning ("Failed to allocate DMA buffer, " - "disabling DMA buffer based screen casting: %s", - error->message); - screen_cast->disable_dma_bufs = TRUE; - return NULL; - } - return dmabuf_handle; +#else + return NULL; +#endif } static MetaRemoteDesktopSession * diff --git a/src/backends/meta-screen-cast.h b/src/backends/meta-screen-cast.h index 1f3982662..38614fdac 100644 --- a/src/backends/meta-screen-cast.h +++ b/src/backends/meta-screen-cast.h @@ -49,15 +49,19 @@ G_DECLARE_FINAL_TYPE (MetaScreenCast, meta_screen_cast, MetaBackend * meta_screen_cast_get_backend (MetaScreenCast *screen_cast); -void meta_screen_cast_disable_dma_bufs (MetaScreenCast *screen_cast); +GArray * meta_screen_cast_query_modifiers (MetaScreenCast *screen_cast, + CoglPixelFormat format); -bool meta_screen_cast_query_modifiers (MetaScreenCast *screen_cast, - CoglPixelFormat format, - uint64_t **modifiers, - int *n_modifiers); +gboolean meta_screen_cast_get_preferred_modifier (MetaScreenCast *screen_cast, + CoglPixelFormat format, + GArray *modifiers, + int width, + int height, + uint64_t *preferred_modifier); CoglDmaBufHandle * meta_screen_cast_create_dma_buf_handle (MetaScreenCast *screen_cast, CoglPixelFormat format, + uint64_t modifier, int width, int height); diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index a1eb44f29..a31bb3ec5 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -62,10 +62,6 @@ #include "meta/main.h" #include "meta-dbus-rtkit1.h" -#ifdef HAVE_REMOTE_DESKTOP -#include "backends/meta-screen-cast.h" -#endif - #ifdef HAVE_EGL_DEVICE #include "backends/native/meta-render-device-egl-stream.h" #endif @@ -162,42 +158,6 @@ meta_backend_native_create_default_seat (MetaBackend *backend, NULL)); } -#ifdef HAVE_REMOTE_DESKTOP -static void -maybe_disable_screen_cast_dma_bufs (MetaBackendNative *native) -{ - MetaBackend *backend = META_BACKEND (native); - MetaRenderer *renderer = meta_backend_get_renderer (backend); - MetaScreenCast *screen_cast = meta_backend_get_screen_cast (backend); - ClutterBackend *clutter_backend = - meta_backend_get_clutter_backend (backend); - CoglContext *cogl_context = - clutter_backend_get_cogl_context (clutter_backend); - CoglRenderer *cogl_renderer = cogl_context_get_renderer (cogl_context); - g_autoptr (GError) error = NULL; - g_autoptr (CoglDmaBufHandle) dmabuf_handle = NULL; - - if (!meta_renderer_is_hardware_accelerated (renderer)) - { - g_message ("Disabling DMA buffer screen sharing " - "(not hardware accelerated)"); - meta_screen_cast_disable_dma_bufs (screen_cast); - } - - dmabuf_handle = cogl_renderer_create_dma_buf (cogl_renderer, - COGL_PIXEL_FORMAT_BGRX_8888, - NULL, 0, - 1, 1, - &error); - if (!dmabuf_handle) - { - g_message ("Disabling DMA buffer screen sharing " - "(implicit modifiers not supported)"); - meta_screen_cast_disable_dma_bufs (screen_cast); - } -} -#endif /* HAVE_REMOTE_DESKTOP */ - static void update_viewports (MetaBackend *backend) { @@ -220,10 +180,6 @@ meta_backend_native_post_init (MetaBackend *backend) META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend); -#ifdef HAVE_REMOTE_DESKTOP - maybe_disable_screen_cast_dma_bufs (backend_native); -#endif - g_clear_pointer (&backend_native->startup_render_devices, g_hash_table_unref);