Explicitly create the clutter context and backend

This changes the setup phase of clutter to not be result of calling an
init function that sets up a few global singletons, via global singleton
setup vfuncs.

The way it worked was that mutter first did some initial setup
(connecting to the X11 server), then set a "custom backend" setup vfunc
global, before calling clutter_init().

During the clutter_init() call, the context and backend was setup by
calling the global singleton getters, which implicitly created the
backend and context on-demand.

This has now changed to mutter explicitly creating a `ClutterContext`
(which is actually a `ClutterMainContext`, but with the name shortened to
be consistent with `CoglContext` and `MetaContext`), calling it with a
backend constructor vfunc and user data pointer.

This function now explicitly creates the backend, without having to go
via the previously set global vfunc.

This changes the behavior of some "get_default()" like functions, which
will now fail if called after mutter has shut down, as when it does so,
it now destroys the backends and contexts, not only its own, but the
clutter ones too.

The "ownership" of the clutter backend is also moved to
`ClutterContext`, and MetaBackend is changed to fetch it via the clutter
context.

This also removed the unused option parsing that existed in clutter.

In some places, NULL checks for fetching the clutter context, or
backend, and fetching the cogl context from the clutter backend, had to
be added.

The reason for this is that some code that handles EGL contexts attempts
to restore the cogl EGL context tracking so that the right EGL context
is used by cogl the next time. This makes no sense to do before Cogl and
Clutter are even initialized, which was the case. It wasn't noticed
because the relevant singletons were initialized on demand via their
"getters".

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
This commit is contained in:
Jonas Ådahl
2021-09-16 11:38:49 +02:00
committed by Marge Bot
parent 92b95b0b4b
commit 8008f0b7b0
15 changed files with 117 additions and 221 deletions

View File

@ -162,7 +162,7 @@ struct _MetaBackendPrivate
WacomDeviceDatabase *wacom_db;
#endif
ClutterBackend *clutter_backend;
ClutterContext *clutter_context;
ClutterSeat *default_seat;
ClutterActor *stage;
@ -257,7 +257,7 @@ meta_backend_dispose (GObject *object)
g_clear_pointer (&priv->stage, clutter_actor_destroy);
g_clear_pointer (&priv->idle_manager, meta_idle_manager_free);
g_clear_object (&priv->renderer);
g_clear_pointer (&priv->clutter_backend, clutter_backend_destroy);
g_clear_pointer (&priv->clutter_context, clutter_context_free);
g_clear_list (&priv->gpus, g_object_unref);
G_OBJECT_CLASS (meta_backend_parent_class)->dispose (object);
@ -1037,11 +1037,11 @@ static GSourceFuncs clutter_source_funcs = {
};
static ClutterBackend *
meta_get_clutter_backend (void)
meta_clutter_backend_constructor (gpointer user_data)
{
MetaBackend *backend = meta_get_backend ();
MetaBackend *backend = META_BACKEND (user_data);
return meta_backend_get_clutter_backend (backend);
return META_BACKEND_GET_CLASS (backend)->create_clutter_backend (backend);
}
static ClutterSeat *
@ -1059,9 +1059,10 @@ init_clutter (MetaBackend *backend,
MetaBackendSource *backend_source;
GSource *source;
clutter_set_custom_backend_func (meta_get_clutter_backend);
if (clutter_init (error) != CLUTTER_INIT_SUCCESS)
priv->clutter_context = clutter_context_new (meta_clutter_backend_constructor,
backend,
error);
if (!priv->clutter_context)
return FALSE;
priv->default_seat = meta_backend_create_default_seat (backend, error);
@ -1526,14 +1527,13 @@ ClutterBackend *
meta_backend_get_clutter_backend (MetaBackend *backend)
{
MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
ClutterContext *clutter_context;
if (!priv->clutter_backend)
{
priv->clutter_backend =
META_BACKEND_GET_CLASS (backend)->create_clutter_backend (backend);
}
clutter_context = priv->clutter_context;
if (!clutter_context)
return NULL;
return priv->clutter_backend;
return clutter_context_get_backend (clutter_context);
}
void

View File

@ -485,7 +485,11 @@ cogl_context_from_renderer_native (MetaRendererNative *renderer_native)
{
MetaRenderer *renderer = META_RENDERER (renderer_native);
MetaBackend *backend = meta_renderer_get_backend (renderer);
ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
ClutterBackend *clutter_backend;
clutter_backend = meta_backend_get_clutter_backend (backend);
if (!clutter_backend)
return NULL;
return clutter_backend_get_cogl_context (clutter_backend);
}

View File

@ -867,7 +867,6 @@ meta_backend_x11_initable_init (GInitable *initable,
priv->xdisplay = xdisplay;
priv->xcb = XGetXCBConnection (priv->xdisplay);
meta_clutter_x11_set_display (xdisplay);
init_xkb_state (x11);

View File

@ -28,6 +28,7 @@
#include "backends/meta-backend-private.h"
#include "backends/meta-renderer.h"
#include "backends/x11/meta-backend-x11.h"
#include "backends/x11/meta-clutter-backend-x11.h"
#include "backends/x11/meta-keymap-x11.h"
#include "backends/x11/meta-seat-x11.h"
@ -76,7 +77,6 @@ static const gchar *atom_names[] = {
/* various flags corresponding to pre init setup calls */
static gboolean clutter_enable_stereo = FALSE;
static Display *_foreign_dpy = NULL;
/* options */
static gboolean clutter_synchronise = FALSE;
@ -117,47 +117,13 @@ meta_clutter_backend_x11_finish_init (ClutterBackend *clutter_backend,
{
MetaClutterBackendX11 *clutter_backend_x11 =
META_CLUTTER_BACKEND_X11 (clutter_backend);
MetaClutterBackendX11Private *priv =
meta_clutter_backend_x11_get_instance_private (clutter_backend_x11);
MetaBackendX11 *backend_x11 = META_BACKEND_X11 (priv->backend);
Atom atoms[N_ATOM_NAMES];
Screen *xscreen;
if (_foreign_dpy)
backend_x11->xdisplay = _foreign_dpy;
/* Only open connection if not already set by prior call to
* clutter_x11_set_display()
*/
if (clutter_backend_x11->xdisplay == NULL)
{
const char *display_name;
display_name = g_getenv ("DISPLAY");
if (display_name && *display_name != '\0')
{
g_debug ("XOpenDisplay on '%s'", display_name);
clutter_backend_x11->xdisplay = XOpenDisplay (display_name);
if (clutter_backend_x11->xdisplay == NULL)
{
g_set_error (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
"Unable to open display '%s'",
display_name);
return FALSE;
}
}
else
{
g_set_error_literal (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
"Unable to open display. You have to set the "
"DISPLAY environment variable, or use the "
"--display command line argument");
return FALSE;
}
}
g_debug ("Getting the X screen");
clutter_backend_x11->xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
/* add event filter for Cogl events */
meta_clutter_backend_x11_add_filter (clutter_backend_x11,
@ -297,8 +263,7 @@ check_onscreen_template (CoglRenderer *renderer,
}
else
{
g_set_error_literal (error, CLUTTER_INIT_ERROR,
CLUTTER_INIT_ERROR_BACKEND,
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
internal_error != NULL
? internal_error->message
: "Creation of a CoglDisplay failed");
@ -543,19 +508,6 @@ meta_clutter_x11_get_default_display (void)
return META_CLUTTER_BACKEND_X11 (clutter_backend)->xdisplay;
}
void
meta_clutter_x11_set_display (Display *xdisplay)
{
if (_clutter_context_is_initialized ())
{
g_warning ("%s() can only be used before calling clutter_init()",
G_STRFUNC);
return;
}
_foreign_dpy= xdisplay;
}
int
meta_clutter_x11_get_default_screen (void)
{

View File

@ -82,7 +82,6 @@ gint meta_clutter_x11_untrap_x_errors (void);
Display *meta_clutter_x11_get_default_display (void);
int meta_clutter_x11_get_default_screen (void);
Window meta_clutter_x11_get_root_window (void);
void meta_clutter_x11_set_display (Display * xdpy);
void meta_clutter_backend_x11_add_filter (MetaClutterBackendX11 *clutter_backend_x11,
MetaX11FilterFunc func,

View File

@ -30,6 +30,7 @@
#include "backends/meta-logical-monitor.h"
#include "backends/meta-renderer-view.h"
#include "backends/meta-renderer.h"
#include "backends/x11/meta-backend-x11.h"
#include "backends/x11/meta-clutter-backend-x11.h"
#include "backends/x11/meta-renderer-x11.h"
#include "cogl/cogl-xlib.h"
@ -81,8 +82,10 @@ get_x11_cogl_winsys_vtable (CoglRenderer *renderer)
static CoglRenderer *
meta_renderer_x11_create_cogl_renderer (MetaRenderer *renderer)
{
MetaBackend *backend = meta_renderer_get_backend (renderer);
MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend);
Display *xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
CoglRenderer *cogl_renderer;
Display *xdisplay = meta_clutter_x11_get_default_display ();
cogl_renderer = cogl_renderer_new ();
cogl_renderer_set_custom_winsys (cogl_renderer, get_x11_cogl_winsys_vtable,