Compare commits
7 Commits
wip/lantw/
...
wip/carlos
Author | SHA1 | Date | |
---|---|---|---|
4d6f99c95d | |||
9e54e404ee | |||
6ec6ea7d3c | |||
d8c4d78f4a | |||
b7a662bfdd | |||
9d61e6e56f | |||
231d9e3c31 |
@ -16,7 +16,7 @@ RUN dnf -y update && dnf -y upgrade && \
|
||||
dnf builddep -y mutter && \
|
||||
|
||||
# Until Fedora catches up with new build-deps
|
||||
dnf install -y 'pkgconfig(graphene-gobject-1.0)' 'pkgconfig(sysprof-capture-3)' && \
|
||||
dnf install -y 'pkgconfig(graphene-gobject-1.0)' 'pkgconfig(sysprof-capture-3)' 'pkgconfig(libcap-ng)' && \
|
||||
|
||||
# For running unit tests
|
||||
dnf install -y xorg-x11-server-Xvfb mesa-dri-drivers dbus dbus-x11 '*/xvfb-run' gdm-lib accountsservice-libs gnome-control-center && \
|
||||
|
@ -79,6 +79,15 @@ G_BEGIN_DECLS
|
||||
EGLDisplay
|
||||
cogl_egl_context_get_egl_display (CoglContext *context);
|
||||
|
||||
gboolean cogl_egl_init_thread (void);
|
||||
|
||||
EGLContext
|
||||
cogl_egl_create_context (EGLDisplay display,
|
||||
EGLConfig config,
|
||||
EGLContext shared_context,
|
||||
const EGLint *attrib_list,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
/* The gobject introspection scanner seems to parse public headers in
|
||||
|
@ -110,6 +110,21 @@ static const CoglFeatureData winsys_feature_data[] =
|
||||
#include "winsys/cogl-winsys-egl-feature-functions.h"
|
||||
};
|
||||
|
||||
static GMainContext *egl_thread_context = NULL;
|
||||
|
||||
typedef struct _CreateEGLContextData
|
||||
{
|
||||
EGLDisplay display;
|
||||
EGLConfig config;
|
||||
EGLContext shared_context;
|
||||
const EGLint *attrib_list;
|
||||
EGLContext context;
|
||||
GError *error;
|
||||
GMutex mutex;
|
||||
GCond cond;
|
||||
gboolean finished;
|
||||
} CreateEGLContextData;
|
||||
|
||||
static GCallback
|
||||
_cogl_winsys_renderer_get_proc_address (CoglRenderer *renderer,
|
||||
const char *name,
|
||||
@ -386,16 +401,14 @@ try_create_context (CoglDisplay *display,
|
||||
|
||||
attribs[i++] = EGL_NONE;
|
||||
|
||||
egl_display->egl_context = eglCreateContext (edpy,
|
||||
config,
|
||||
EGL_NO_CONTEXT,
|
||||
attribs);
|
||||
egl_display->egl_context = cogl_egl_create_context (edpy,
|
||||
config,
|
||||
EGL_NO_CONTEXT,
|
||||
attribs,
|
||||
error);
|
||||
|
||||
if (egl_display->egl_context == EGL_NO_CONTEXT)
|
||||
{
|
||||
error_message = "Unable to create a suitable EGL context";
|
||||
goto fail;
|
||||
}
|
||||
goto err;
|
||||
|
||||
if (egl_renderer->private_features &
|
||||
COGL_EGL_WINSYS_FEATURE_CONTEXT_PRIORITY)
|
||||
@ -965,3 +978,206 @@ cogl_egl_context_get_egl_display (CoglContext *context)
|
||||
|
||||
return egl_renderer->edpy;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
init_egl_context_thread (gpointer data)
|
||||
{
|
||||
GMainContext *main_context = data;
|
||||
GMainLoop *main_loop = g_main_loop_new (main_context, FALSE);
|
||||
|
||||
g_main_loop_run (main_loop);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
cogl_egl_init_thread (void)
|
||||
{
|
||||
g_autoptr (GMainContext) main_context = NULL;
|
||||
g_autoptr (GThread) thread = NULL;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
if (egl_thread_context != NULL)
|
||||
return TRUE;
|
||||
|
||||
main_context = g_main_context_new ();
|
||||
thread = g_thread_try_new ("EGL context generator thread",
|
||||
init_egl_context_thread,
|
||||
main_context, &error);
|
||||
if (!thread)
|
||||
{
|
||||
g_warning ("Failed to create EGL Context generator thread: %s",
|
||||
error->message);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
egl_thread_context = g_steal_pointer (&main_context);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static CreateEGLContextData *
|
||||
create_egl_context_data_new (EGLDisplay display,
|
||||
EGLConfig config,
|
||||
EGLContext shared_context,
|
||||
const EGLint *attrib_list)
|
||||
{
|
||||
CreateEGLContextData *data;
|
||||
|
||||
data = g_new0 (CreateEGLContextData, 1);
|
||||
data->display = display;
|
||||
data->config = config;
|
||||
data->shared_context = shared_context;
|
||||
data->attrib_list = attrib_list;
|
||||
data->context = EGL_NO_CONTEXT;
|
||||
g_mutex_init (&data->mutex);
|
||||
g_cond_init (&data->cond);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static const char *
|
||||
get_egl_error_str (EGLint error_number)
|
||||
{
|
||||
switch (error_number)
|
||||
{
|
||||
case EGL_SUCCESS:
|
||||
return "The last function succeeded without error.";
|
||||
break;
|
||||
case EGL_NOT_INITIALIZED:
|
||||
return "EGL is not initialized, or could not be initialized, for the specified EGL display connection.";
|
||||
break;
|
||||
case EGL_BAD_ACCESS:
|
||||
return "EGL cannot access a requested resource (for example a context is bound in another thread).";
|
||||
break;
|
||||
case EGL_BAD_ALLOC:
|
||||
return "EGL failed to allocate resources for the requested operation.";
|
||||
break;
|
||||
case EGL_BAD_ATTRIBUTE:
|
||||
return "An unrecognized attribute or attribute value was passed in the attribute list.";
|
||||
break;
|
||||
case EGL_BAD_CONTEXT:
|
||||
return "An EGLContext argument does not name a valid EGL rendering context.";
|
||||
break;
|
||||
case EGL_BAD_CONFIG:
|
||||
return "An EGLConfig argument does not name a valid EGL frame buffer configuration.";
|
||||
break;
|
||||
case EGL_BAD_CURRENT_SURFACE:
|
||||
return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid.";
|
||||
break;
|
||||
case EGL_BAD_DISPLAY:
|
||||
return "An EGLDisplay argument does not name a valid EGL display connection.";
|
||||
break;
|
||||
case EGL_BAD_SURFACE:
|
||||
return "An EGLSurface argument does not name a valid surface (window, pixel buffer or pixmap) configured for GL rendering.";
|
||||
break;
|
||||
case EGL_BAD_MATCH:
|
||||
return "Arguments are inconsistent (for example, a valid context requires buffers not supplied by a valid surface).";
|
||||
break;
|
||||
case EGL_BAD_PARAMETER:
|
||||
return "One or more argument values are invalid.";
|
||||
break;
|
||||
case EGL_BAD_NATIVE_PIXMAP:
|
||||
return "A NativePixmapType argument does not refer to a valid native pixmap.";
|
||||
break;
|
||||
case EGL_BAD_NATIVE_WINDOW:
|
||||
return "A NativeWindowType argument does not refer to a valid native window.";
|
||||
break;
|
||||
case EGL_CONTEXT_LOST:
|
||||
return "A power management event has occurred. The application must destroy all contexts and reinitialise OpenGL ES state and objects to continue rendering. ";
|
||||
break;
|
||||
case EGL_BAD_STREAM_KHR:
|
||||
return "An EGLStreamKHR argument does not name a valid EGL stream.";
|
||||
break;
|
||||
case EGL_BAD_STATE_KHR:
|
||||
return "An EGLStreamKHR argument is not in a valid state";
|
||||
break;
|
||||
case EGL_BAD_DEVICE_EXT:
|
||||
return "An EGLDeviceEXT argument does not name a valid EGL device.";
|
||||
break;
|
||||
case EGL_BAD_OUTPUT_LAYER_EXT:
|
||||
return "An EGLOutputLayerEXT argument does not name a valid EGL output layer.";
|
||||
default:
|
||||
return "Unknown error";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_egl_error (GError **error)
|
||||
{
|
||||
EGLint error_number;
|
||||
const char *error_str;
|
||||
|
||||
if (!error)
|
||||
return;
|
||||
|
||||
error_number = eglGetError ();
|
||||
error_str = get_egl_error_str (error_number);
|
||||
g_set_error_literal (error, COGL_WINSYS_ERROR,
|
||||
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
||||
error_str);
|
||||
}
|
||||
|
||||
/* Executed in the EGL context generator thread */
|
||||
static gboolean
|
||||
create_context_in_thread (gpointer user_data)
|
||||
{
|
||||
CreateEGLContextData *data = user_data;
|
||||
|
||||
g_mutex_lock (&data->mutex);
|
||||
data->context = eglCreateContext (data->display,
|
||||
data->config,
|
||||
data->shared_context,
|
||||
data->attrib_list);
|
||||
if (data->context == EGL_NO_CONTEXT)
|
||||
set_egl_error (&data->error);
|
||||
|
||||
data->finished = TRUE;
|
||||
g_cond_signal (&data->cond);
|
||||
g_mutex_unlock (&data->mutex);
|
||||
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
EGLContext
|
||||
cogl_egl_create_context (EGLDisplay display,
|
||||
EGLConfig config,
|
||||
EGLContext shared_context,
|
||||
const EGLint *attrib_list,
|
||||
GError **error)
|
||||
{
|
||||
CreateEGLContextData *data;
|
||||
EGLContext context;
|
||||
GSource *source;
|
||||
|
||||
if (!cogl_egl_init_thread ())
|
||||
{
|
||||
g_set_error_literal (error, COGL_WINSYS_ERROR,
|
||||
COGL_WINSYS_ERROR_CREATE_CONTEXT,
|
||||
"EGL thread initialization failed");
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
data = create_egl_context_data_new (display, config,
|
||||
shared_context, attrib_list);
|
||||
g_mutex_lock (&data->mutex);
|
||||
|
||||
source = g_idle_source_new ();
|
||||
g_source_set_callback (source, create_context_in_thread,
|
||||
data, NULL);
|
||||
g_source_attach (source, egl_thread_context);
|
||||
g_source_unref (source);
|
||||
|
||||
while (!data->finished)
|
||||
g_cond_wait (&data->cond, &data->mutex);
|
||||
|
||||
context = data->context;
|
||||
if (data->error)
|
||||
g_propagate_error (error, data->error);
|
||||
|
||||
g_mutex_unlock (&data->mutex);
|
||||
g_free (data);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
@ -67,3 +67,6 @@
|
||||
/* Either <sys/random.h> or <linux/random.h> */
|
||||
#mesondefine HAVE_SYS_RANDOM
|
||||
#mesondefine HAVE_LINUX_RANDOM
|
||||
|
||||
/* Defined if libcap-ng is available */
|
||||
#mesondefine HAVE_LIBCAPNG
|
||||
|
@ -120,10 +120,6 @@
|
||||
framebuffers instead of window content,
|
||||
to manage HiDPI monitors. Does not
|
||||
require a restart.
|
||||
• “rt-scheduler” — makes mutter request a low priority
|
||||
real-time scheduling. The executable
|
||||
or user must have CAP_SYS_NICE.
|
||||
Requires a restart.
|
||||
• “autostart-xwayland” — initializes Xwayland lazily if there are
|
||||
X11 clients. Requires restart.
|
||||
</description>
|
||||
|
@ -36,6 +36,7 @@ libstartup_notification_req = '>= 0.7'
|
||||
libcanberra_req = '>= 0.26'
|
||||
libwacom_req = '>= 0.13'
|
||||
atk_req = '>= 2.5.3'
|
||||
libcapng_req = '>= 0.7.9'
|
||||
|
||||
# optional version requirements
|
||||
udev_req = '>= 228'
|
||||
@ -127,6 +128,7 @@ xau_dep = dependency('xau')
|
||||
ice_dep = dependency('ice')
|
||||
atk_dep = dependency('atk', version: atk_req)
|
||||
libcanberra_dep = dependency('libcanberra', version: libcanberra_req)
|
||||
libcapng_dep = dependency('libcap-ng', required: get_option('libcapng'))
|
||||
|
||||
# For now always require X11 support
|
||||
have_x11 = true
|
||||
@ -258,6 +260,7 @@ have_core_tests = false
|
||||
have_cogl_tests = false
|
||||
have_clutter_tests = false
|
||||
have_installed_tests = false
|
||||
have_libcapng = libcapng_dep.found()
|
||||
|
||||
if have_tests
|
||||
have_core_tests = get_option('core_tests')
|
||||
@ -364,6 +367,7 @@ cdata.set('HAVE_SM', have_sm)
|
||||
cdata.set('HAVE_STARTUP_NOTIFICATION', have_startup_notification)
|
||||
cdata.set('HAVE_INTROSPECTION', have_introspection)
|
||||
cdata.set('HAVE_PROFILER', have_profiler)
|
||||
cdata.set('HAVE_LIBCAPNG', have_libcapng)
|
||||
|
||||
xkb_base = xkeyboard_config_dep.get_pkgconfig_variable('xkb_base')
|
||||
cdata.set_quoted('XKB_BASE', xkb_base)
|
||||
@ -445,6 +449,7 @@ output = [
|
||||
' Startup notification..... ' + have_startup_notification.to_string(),
|
||||
' Introspection............ ' + have_introspection.to_string(),
|
||||
' Profiler................. ' + have_profiler.to_string(),
|
||||
' libcap-ng................ ' + have_libcapng.to_string(),
|
||||
'',
|
||||
' Tests:',
|
||||
'',
|
||||
|
@ -152,3 +152,9 @@ option('xwayland_grab_default_access_rules',
|
||||
value: 'gnome-boxes,remote-viewer,virt-viewer,virt-manager,vinagre,vncviewer,Xephyr',
|
||||
description: 'Comma delimited list of applications ressources or class allowed to issue X11 grabs in Xwayland'
|
||||
)
|
||||
|
||||
option('libcapng',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Enable libcap-ng support'
|
||||
)
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-egl.h"
|
||||
#include "backends/meta-egl-ext.h"
|
||||
#include "cogl/cogl-egl.h"
|
||||
#include "meta/util.h"
|
||||
|
||||
struct _MetaEgl
|
||||
@ -506,16 +507,9 @@ meta_egl_create_context (MetaEgl *egl,
|
||||
const EGLint *attrib_list,
|
||||
GError **error)
|
||||
{
|
||||
EGLContext context;
|
||||
|
||||
context = eglCreateContext (display, config, share_context, attrib_list);
|
||||
if (context == EGL_NO_CONTEXT)
|
||||
{
|
||||
set_egl_error (error);
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
return context;
|
||||
return cogl_egl_create_context (display, config,
|
||||
share_context, attrib_list,
|
||||
error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
@ -33,8 +33,7 @@ typedef enum _MetaExperimentalFeature
|
||||
META_EXPERIMENTAL_FEATURE_NONE = 0,
|
||||
META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER = (1 << 0),
|
||||
META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS = (1 << 1),
|
||||
META_EXPERIMENTAL_FEATURE_RT_SCHEDULER = (1 << 2),
|
||||
META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND = (1 << 3),
|
||||
META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND = (1 << 2),
|
||||
} MetaExperimentalFeature;
|
||||
|
||||
#define META_TYPE_SETTINGS (meta_settings_get_type ())
|
||||
|
@ -264,8 +264,6 @@ experimental_features_handler (GVariant *features_variant,
|
||||
features |= META_EXPERIMENTAL_FEATURE_SCALE_MONITOR_FRAMEBUFFER;
|
||||
else if (g_str_equal (feature, "kms-modifiers"))
|
||||
features |= META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS;
|
||||
else if (g_str_equal (feature, "rt-scheduler"))
|
||||
features |= META_EXPERIMENTAL_FEATURE_RT_SCHEDULER;
|
||||
else if (g_str_equal (feature, "autostart-xwayland"))
|
||||
features |= META_EXPERIMENTAL_FEATURE_AUTOSTART_XWAYLAND;
|
||||
else
|
||||
|
@ -341,7 +341,6 @@ static void
|
||||
meta_backend_native_post_init (MetaBackend *backend)
|
||||
{
|
||||
ClutterDeviceManager *manager = clutter_device_manager_get_default ();
|
||||
MetaSettings *settings = meta_backend_get_settings (backend);
|
||||
|
||||
META_BACKEND_CLASS (meta_backend_native_parent_class)->post_init (backend);
|
||||
|
||||
@ -349,20 +348,6 @@ meta_backend_native_post_init (MetaBackend *backend)
|
||||
NULL, NULL);
|
||||
meta_device_manager_native_set_relative_motion_filter (manager, relative_motion_filter,
|
||||
meta_backend_get_monitor_manager (backend));
|
||||
|
||||
if (meta_settings_is_experimental_feature_enabled (settings,
|
||||
META_EXPERIMENTAL_FEATURE_RT_SCHEDULER))
|
||||
{
|
||||
int retval;
|
||||
struct sched_param sp = {
|
||||
.sched_priority = sched_get_priority_min (SCHED_RR)
|
||||
};
|
||||
|
||||
retval = sched_setscheduler (0, SCHED_RR | SCHED_RESET_ON_FORK, &sp);
|
||||
|
||||
if (retval != 0)
|
||||
g_warning ("Failed to set RT scheduler: %m");
|
||||
}
|
||||
}
|
||||
|
||||
static MetaMonitorManager *
|
||||
|
@ -3509,6 +3509,7 @@ create_secondary_egl_context (MetaEgl *egl,
|
||||
{
|
||||
EGLint attributes[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||
EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
|
@ -66,6 +66,10 @@
|
||||
#include <girepository.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBCAPNG
|
||||
#include <cap-ng.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_NATIVE_BACKEND) && defined(HAVE_WAYLAND)
|
||||
#include <systemd/sd-login.h>
|
||||
#endif /* HAVE_WAYLAND && HAVE_NATIVE_BACKEND */
|
||||
@ -522,6 +526,22 @@ meta_override_compositor_configuration (MetaCompositorType compositor_type,
|
||||
_backend_gtype_override = backend_gtype;
|
||||
}
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
static void
|
||||
meta_set_scheduler (void)
|
||||
{
|
||||
int retval;
|
||||
struct sched_param sp = {
|
||||
.sched_priority = sched_get_priority_min (SCHED_RR)
|
||||
};
|
||||
|
||||
retval = sched_setscheduler (0, SCHED_RR | SCHED_RESET_ON_FORK, &sp);
|
||||
|
||||
if (retval != 0)
|
||||
g_warning ("Failed to set RT scheduler: %m");
|
||||
}
|
||||
#endif /* HAVE_NATIVE_BACKEND */
|
||||
|
||||
/**
|
||||
* meta_init: (skip)
|
||||
*
|
||||
@ -553,8 +573,6 @@ meta_init (void)
|
||||
g_strerror (errno));
|
||||
#endif
|
||||
|
||||
g_unix_signal_add (SIGTERM, on_sigterm, NULL);
|
||||
|
||||
if (g_getenv ("MUTTER_VERBOSE"))
|
||||
meta_set_verbose (TRUE);
|
||||
if (g_getenv ("MUTTER_DEBUG"))
|
||||
@ -575,6 +593,21 @@ meta_init (void)
|
||||
meta_set_is_wayland_compositor (TRUE);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NATIVE_BACKEND
|
||||
if (backend_gtype == META_TYPE_BACKEND_NATIVE)
|
||||
{
|
||||
meta_set_scheduler ();
|
||||
cogl_egl_init_thread ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBCAPNG
|
||||
capng_clear (CAPNG_SELECT_BOTH);
|
||||
capng_apply (CAPNG_SELECT_BOTH);
|
||||
#endif
|
||||
|
||||
g_unix_signal_add (SIGTERM, on_sigterm, NULL);
|
||||
|
||||
if (g_get_home_dir ())
|
||||
if (chdir (g_get_home_dir ()) < 0)
|
||||
meta_warning ("Could not change to home directory %s.\n",
|
||||
|
@ -18,6 +18,7 @@ mutter_pkg_deps = [
|
||||
glib_dep,
|
||||
gsettings_desktop_schemas_dep,
|
||||
gtk3_dep,
|
||||
libcapng_dep,
|
||||
pango_dep,
|
||||
]
|
||||
|
||||
|
Reference in New Issue
Block a user