Make mutter manage its own clutter backends

Introduce two new clutter backends: MetaClutterBackendX11 and
MetaClutterBackendNative. They are so far only wrap ClutterBackendX11
and ClutterBackendEglNative respectively, but the aim is to move things
from the original clutter backends when needed.

https://bugzilla.gnome.org/show_bug.cgi?id=768976
This commit is contained in:
Jonas Ådahl 2016-05-04 16:19:23 +08:00
parent a1bedd4b1c
commit 90de521799
18 changed files with 353 additions and 34 deletions

View File

@ -48,6 +48,7 @@
#include "clutter-debug.h"
#include "clutter-event-private.h"
#include "clutter-marshal.h"
#include "clutter-mutter.h"
#include "clutter-private.h"
#include "clutter-stage-manager-private.h"
#include "clutter-stage-private.h"
@ -236,10 +237,7 @@ clutter_backend_do_real_create_context (ClutterBackend *backend,
internal_error = NULL;
CLUTTER_NOTE (BACKEND, "Creating Cogl renderer");
if (klass->get_renderer != NULL)
backend->cogl_renderer = klass->get_renderer (backend, &internal_error);
else
backend->cogl_renderer = cogl_renderer_new ();
backend->cogl_renderer = klass->get_renderer (backend, &internal_error);
if (backend->cogl_renderer == NULL)
goto error;
@ -510,6 +508,8 @@ clutter_backend_real_create_stage (ClutterBackend *backend,
static const char *allowed_backends;
static ClutterBackend * (* custom_backend_func) (void);
static const struct {
const char *name;
ClutterBackend * (* create_backend) (void);
@ -523,6 +523,12 @@ static const struct {
{ NULL, NULL },
};
void
clutter_set_custom_backend_func (ClutterBackend *(* func) (void))
{
custom_backend_func = func;
}
ClutterBackend *
_clutter_create_backend (void)
{
@ -532,6 +538,16 @@ _clutter_create_backend (void)
char **backends;
int i;
if (custom_backend_func)
{
retval = custom_backend_func ();
if (!retval)
g_error ("Failed to create custom backend.");
return retval;
}
if (allowed_backends == NULL)
allowed_backends = "*";

View File

@ -128,6 +128,8 @@
#define CLUTTER_AVAILABLE_IN_ALL _CLUTTER_EXTERN
#define CLUTTER_AVAILABLE_IN_MUTTER _CLUTTER_EXTERN
/**
* CLUTTER_VERSION_MIN_REQUIRED:
*

View File

@ -0,0 +1,36 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Copyright (C) 2016 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __CLUTTER_MUTTER_H__
#define __CLUTTER_MUTTER_H__
#define __CLUTTER_H_INSIDE__
#include "clutter-backend.h"
#include "clutter-macros.h"
CLUTTER_AVAILABLE_IN_MUTTER
void clutter_set_custom_backend_func (ClutterBackend *(* func) (void));
#undef __CLUTTER_H_INSIDE__
#endif /* __CLUTTER_MUTTER_H__ */

View File

@ -47,6 +47,8 @@ G_BEGIN_DECLS
typedef struct _ClutterBackendEglNative ClutterBackendEglNative;
typedef struct _ClutterBackendEglNativeClass ClutterBackendEglNativeClass;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackendEglNative, g_object_unref)
struct _ClutterBackendEglNative
{
ClutterBackend parent_instance;
@ -66,6 +68,7 @@ struct _ClutterBackendEglNativeClass
ClutterBackendClass parent_class;
};
CLUTTER_AVAILABLE_IN_MUTTER
GType clutter_backend_egl_native_get_type (void) G_GNUC_CONST;
ClutterBackend *clutter_backend_egl_native_new (void);

View File

@ -48,6 +48,8 @@ typedef struct _ClutterBackendX11Class ClutterBackendX11Class;
typedef struct _ClutterEventX11 ClutterEventX11;
typedef struct _ClutterX11EventFilter ClutterX11EventFilter;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterBackendX11, g_object_unref)
struct _ClutterX11EventFilter
{
ClutterX11FilterFunc func;
@ -116,6 +118,7 @@ struct _ClutterBackendX11Class
ClutterBackendClass parent_class;
};
CLUTTER_AVAILABLE_IN_MUTTER
GType clutter_backend_x11_get_type (void) G_GNUC_CONST;
ClutterBackend *clutter_backend_x11_new (void);

View File

@ -108,6 +108,8 @@ libmutter_la_SOURCES = \
backends/x11/meta-backend-x11.h \
backends/x11/meta-barrier-x11.c \
backends/x11/meta-barrier-x11.h \
backends/x11/meta-clutter-backend-x11.c \
backends/x11/meta-clutter-backend-x11.h \
backends/x11/meta-cursor-renderer-x11.c \
backends/x11/meta-cursor-renderer-x11.h \
backends/x11/nested/meta-cursor-renderer-x11-nested.c \
@ -328,6 +330,8 @@ libmutter_la_SOURCES += \
backends/native/meta-backend-native-private.h \
backends/native/meta-barrier-native.c \
backends/native/meta-barrier-native.h \
backends/native/meta-clutter-backend-native.c \
backends/native/meta-clutter-backend-native.h \
backends/native/meta-cursor-renderer-native.c \
backends/native/meta-cursor-renderer-native.h \
backends/native/meta-idle-monitor-native.c \

View File

@ -35,6 +35,7 @@
#include "meta-cursor-renderer.h"
#include "meta-monitor-manager-private.h"
#include "backends/meta-pointer-constraint.h"
#include "core/util-private.h"
#define DEFAULT_XKB_RULES_FILE "evdev"
#define DEFAULT_XKB_MODEL "pc105+inet"
@ -60,6 +61,8 @@ struct _MetaBackendClass
{
GObjectClass parent_class;
ClutterBackend * (* create_clutter_backend) (MetaBackend *backend);
void (* post_init) (MetaBackend *backend);
MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend,
@ -99,6 +102,8 @@ struct _MetaBackendClass
double *dy_unaccel);
};
void meta_init_backend (MetaBackendType backend_type);
MetaIdleMonitor * meta_backend_get_idle_monitor (MetaBackend *backend,
int device_id);
MetaMonitorManager * meta_backend_get_monitor_manager (MetaBackend *backend);

View File

@ -26,6 +26,7 @@
#include <stdlib.h>
#include <clutter/clutter-mutter.h>
#include <meta/meta-backend.h>
#include "meta-backend-private.h"
#include "meta-input-settings-private.h"
@ -63,6 +64,7 @@ struct _MetaBackendPrivate
MetaCursorRenderer *cursor_renderer;
MetaInputSettings *input_settings;
ClutterBackend *clutter_backend;
ClutterActor *stage;
guint device_update_idle_id;
@ -610,30 +612,6 @@ meta_backend_set_client_pointer_constraint (MetaBackend *backend,
backend->client_pointer_constraint = g_object_ref (constraint);
}
static GType
get_backend_type (void)
{
#if defined(CLUTTER_WINDOWING_X11)
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
return META_TYPE_BACKEND_X11;
#endif
#if defined(CLUTTER_WINDOWING_EGL) && defined(HAVE_NATIVE_BACKEND)
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_EGL))
return META_TYPE_BACKEND_NATIVE;
#endif
g_assert_not_reached ();
}
static void
meta_create_backend (void)
{
/* meta_backend_init() above install the backend globally so
* so meta_get_backend() works even during initialization. */
g_object_new (get_backend_type (), NULL);
}
/* Mutter is responsible for pulling events off the X queue, so Clutter
* doesn't need (and shouldn't) run its normal event source which polls
* the X fd, but we do have to deal with dispatching events that accumulate
@ -682,6 +660,54 @@ static GSourceFuncs event_funcs = {
event_dispatch
};
static ClutterBackend *
meta_backend_get_clutter_backend (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
if (!priv->clutter_backend)
{
priv->clutter_backend =
META_BACKEND_GET_CLASS (backend)->create_clutter_backend (backend);
}
return priv->clutter_backend;
}
static ClutterBackend *
meta_get_clutter_backend (void)
{
MetaBackend *backend = meta_get_backend ();
return meta_backend_get_clutter_backend (backend);
}
void
meta_init_backend (MetaBackendType backend_type)
{
GType type;
switch (backend_type)
{
case META_BACKEND_TYPE_X11:
type = META_TYPE_BACKEND_X11;
break;
#ifdef HAVE_NATIVE_BACKEND
case META_BACKEND_TYPE_NATIVE:
type = META_TYPE_BACKEND_NATIVE;
break;
#endif
default:
g_assert_not_reached ();
}
/* meta_backend_init() above install the backend globally so
* so meta_get_backend() works even during initialization. */
g_object_new (type, NULL);
}
/**
* meta_clutter_init: (skip)
*/
@ -691,7 +717,7 @@ meta_clutter_init (void)
ClutterSettings *clutter_settings;
GSource *source;
meta_create_backend ();
clutter_set_custom_backend_func (meta_get_clutter_backend);
if (clutter_init (NULL, NULL) != CLUTTER_INIT_SUCCESS)
{

View File

@ -38,6 +38,7 @@
#include "meta-launcher.h"
#include "backends/meta-cursor-tracker-private.h"
#include "backends/meta-pointer-constraint.h"
#include "backends/native/meta-clutter-backend-native.h"
#include <stdlib.h>
@ -241,6 +242,12 @@ pointer_constrain_callback (ClutterInputDevice *device,
constrain_all_screen_monitors(device, monitors, n_monitors, new_x, new_y);
}
static ClutterBackend *
meta_backend_native_create_clutter_backend (MetaBackend *backend)
{
return g_object_new (META_TYPE_CLUTTER_BACKEND_NATIVE, NULL);
}
static void
meta_backend_native_post_init (MetaBackend *backend)
{
@ -357,7 +364,10 @@ meta_backend_native_class_init (MetaBackendNativeClass *klass)
object_class->finalize = meta_backend_native_finalize;
backend_class->create_clutter_backend = meta_backend_native_create_clutter_backend;
backend_class->post_init = meta_backend_native_post_init;
backend_class->create_idle_monitor = meta_backend_native_create_idle_monitor;
backend_class->create_monitor_manager = meta_backend_native_create_monitor_manager;
backend_class->create_cursor_renderer = meta_backend_native_create_cursor_renderer;

View File

@ -26,6 +26,7 @@
#define META_BACKEND_NATIVE_H
#include "backends/meta-backend-private.h"
#include "backends/native/meta-clutter-backend-native.h"
#define META_TYPE_BACKEND_NATIVE (meta_backend_native_get_type ())
#define META_BACKEND_NATIVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKEND_NATIVE, MetaBackendNative))

View File

@ -0,0 +1,49 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2016 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Jonas Ådahl <jadahl@gmail.com>
*/
#include "config.h"
#include <glib-object.h>
#include "clutter/clutter.h"
#include "clutter/egl/clutter-backend-eglnative.h"
#include "backends/native/meta-clutter-backend-native.h"
struct _MetaClutterBackendNative
{
ClutterBackendEglNative parent;
};
G_DEFINE_TYPE (MetaClutterBackendNative, meta_clutter_backend_native,
CLUTTER_TYPE_BACKEND_EGL_NATIVE)
static void
meta_clutter_backend_native_init (MetaClutterBackendNative *clutter_backend_nativen)
{
}
static void
meta_clutter_backend_native_class_init (MetaClutterBackendNativeClass *klass)
{
}

View File

@ -0,0 +1,38 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2016 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Jonas Ådahl <jadahl@gmail.com>
*/
#ifndef META_CLUTTER_BACKEND_NATIVE_H
#define META_CLUTTER_BACKEND_NATIVE_H
#include <glib-object.h>
#include "clutter/clutter.h"
#include "clutter/egl/clutter-backend-eglnative.h"
#define META_TYPE_CLUTTER_BACKEND_NATIVE (meta_clutter_backend_native_get_type ())
G_DECLARE_FINAL_TYPE (MetaClutterBackendNative, meta_clutter_backend_native,
META, CLUTTER_BACKEND_NATIVE,
ClutterBackendEglNative)
#endif /* META_CLUTTER_BACKEND_NATIVE_H */

View File

@ -29,6 +29,7 @@
#include "meta-backend-x11.h"
#include <clutter.h>
#include <clutter/x11/clutter-x11.h>
#include <X11/extensions/sync.h>
@ -41,6 +42,7 @@
#include "meta-monitor-manager-xrandr.h"
#include "backends/meta-monitor-manager-dummy.h"
#include "backends/x11/nested/meta-cursor-renderer-x11-nested.h"
#include "backends/x11/meta-clutter-backend-x11.h"
#include "meta-cursor-renderer-x11.h"
#ifdef HAVE_WAYLAND
#include "wayland/meta-wayland.h"
@ -499,6 +501,12 @@ meta_backend_x11_post_init (MetaBackend *backend)
META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
}
static ClutterBackend *
meta_backend_x11_create_clutter_backend (MetaBackend *backend)
{
return g_object_new (META_TYPE_CLUTTER_BACKEND_X11, NULL);
}
static MetaIdleMonitor *
meta_backend_x11_create_idle_monitor (MetaBackend *backend,
int device_id)
@ -865,6 +873,7 @@ meta_backend_x11_class_init (MetaBackendX11Class *klass)
{
MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
backend_class->create_clutter_backend = meta_backend_x11_create_clutter_backend;
backend_class->post_init = meta_backend_x11_post_init;
backend_class->create_idle_monitor = meta_backend_x11_create_idle_monitor;
backend_class->create_monitor_manager = meta_backend_x11_create_monitor_manager;

View File

@ -29,6 +29,8 @@
#include <X11/Xlib.h>
#include "backends/x11/meta-clutter-backend-x11.h"
#define META_TYPE_BACKEND_X11 (meta_backend_x11_get_type ())
#define META_BACKEND_X11(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKEND_X11, MetaBackendX11))
#define META_BACKEND_X11_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BACKEND_X11, MetaBackendX11Class))

View File

@ -0,0 +1,48 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2016 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Jonas Ådahl <jadahl@gmail.com>
*/
#include "config.h"
#include <glib-object.h>
#include "backends/x11/meta-clutter-backend-x11.h"
#include "clutter/clutter.h"
struct _MetaClutterBackendX11
{
ClutterBackendX11 parent;
};
G_DEFINE_TYPE (MetaClutterBackendX11, meta_clutter_backend_x11,
CLUTTER_TYPE_BACKEND_X11)
static void
meta_clutter_backend_x11_init (MetaClutterBackendX11 *clutter_backend_x11)
{
}
static void
meta_clutter_backend_x11_class_init (MetaClutterBackendX11Class *klass)
{
}

View File

@ -0,0 +1,38 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/*
* Copyright (C) 2016 Red Hat
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by:
* Jonas Ådahl <jadahl@gmail.com>
*/
#ifndef META_CLUTTER_BACKEND_X11_H
#define META_CLUTTER_BACKEND_X11_H
#include <glib-object.h>
#include "clutter/clutter.h"
#include "clutter/x11/clutter-backend-x11.h"
#define META_TYPE_CLUTTER_BACKEND_X11 (meta_clutter_backend_x11_get_type ())
G_DECLARE_FINAL_TYPE (MetaClutterBackendX11, meta_clutter_backend_x11,
META, CLUTTER_BACKEND_X11,
ClutterBackendX11)
#endif /* META_CLUTTER_BACKEND_X11_H */

View File

@ -82,6 +82,8 @@
#include "wayland/meta-wayland.h"
# endif
#include "backends/meta-backend-private.h"
#if defined(HAVE_NATIVE_BACKEND) && defined(HAVE_WAYLAND)
#include <systemd/sd-login.h>
#endif
@ -371,7 +373,8 @@ check_for_wayland_session_type (void)
#endif
static void
init_backend (void)
calculate_compositor_configuration (MetaCompositorType *compositor_type,
MetaBackendType *backend_type)
{
#ifdef HAVE_WAYLAND
gboolean run_as_wayland_compositor = opt_wayland;
@ -388,16 +391,19 @@ init_backend (void)
#ifdef CLUTTER_WINDOWING_EGL
if (opt_display_server || (run_as_wayland_compositor && !opt_nested))
clutter_set_windowing_backend (CLUTTER_WINDOWING_EGL);
*backend_type = META_BACKEND_TYPE_NATIVE;
else
#endif
#endif
#endif
clutter_set_windowing_backend (CLUTTER_WINDOWING_X11);
*backend_type = META_BACKEND_TYPE_X11;
#ifdef HAVE_WAYLAND
meta_set_is_wayland_compositor (run_as_wayland_compositor);
if (run_as_wayland_compositor)
*compositor_type = META_COMPOSITOR_TYPE_WAYLAND;
else
#endif
*compositor_type = META_COMPOSITOR_TYPE_X11;
}
/**
@ -411,6 +417,8 @@ meta_init (void)
{
struct sigaction act;
sigset_t empty_mask;
MetaCompositorType compositor_type;
MetaBackendType backend_type;
sigemptyset (&empty_mask);
act.sa_handler = SIG_IGN;
@ -432,7 +440,10 @@ meta_init (void)
if (g_getenv ("MUTTER_DEBUG"))
meta_set_debugging (TRUE);
init_backend ();
calculate_compositor_configuration (&compositor_type, &backend_type);
if (compositor_type == META_COMPOSITOR_TYPE_WAYLAND)
meta_set_is_wayland_compositor (TRUE);
if (g_get_home_dir ())
if (chdir (g_get_home_dir ()) < 0)
@ -455,6 +466,8 @@ meta_init (void)
if (!meta_is_wayland_compositor ())
meta_select_display (opt_display_name);
meta_init_backend (backend_type);
meta_clutter_init ();
#ifdef HAVE_WAYLAND

View File

@ -28,6 +28,22 @@
#include <meta/util.h>
#include <glib/gi18n-lib.h>
typedef enum _MetaCompositorType
{
#ifdef HAVE_WAYLAND
META_COMPOSITOR_TYPE_WAYLAND,
#endif
META_COMPOSITOR_TYPE_X11,
} MetaCompositorType;
typedef enum _MetaBackendType
{
#ifdef HAVE_NATIVE_BACKEND
META_BACKEND_TYPE_NATIVE,
#endif
META_BACKEND_TYPE_X11,
} MetaBackendType;
void meta_set_verbose (gboolean setting);
void meta_set_debugging (gboolean setting);
void meta_set_syncing (gboolean setting);