Delay default stage creation
The default stage creation should be delayed as much as possible, ideally at the end of the init() process.
This commit is contained in:
parent
3191ea1195
commit
6fbed66add
6 changed files with 126 additions and 61 deletions
|
@ -425,6 +425,14 @@ _clutter_backend_get_features (ClutterBackend *backend)
|
||||||
g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), 0);
|
g_return_val_if_fail (CLUTTER_IS_BACKEND (backend), 0);
|
||||||
|
|
||||||
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
klass = CLUTTER_BACKEND_GET_CLASS (backend);
|
||||||
|
|
||||||
|
/* we need to have a context here; so we create the
|
||||||
|
* GL context first and the ask for features. if the
|
||||||
|
* context already exists this should be a no-op
|
||||||
|
*/
|
||||||
|
if (klass->create_context)
|
||||||
|
klass->create_context (backend, NULL);
|
||||||
|
|
||||||
if (klass->get_features)
|
if (klass->get_features)
|
||||||
return klass->get_features (backend);
|
return klass->get_features (backend);
|
||||||
|
|
||||||
|
|
|
@ -1505,40 +1505,9 @@ clutter_init_real (GError **error)
|
||||||
if (!_clutter_backend_post_parse (backend, error))
|
if (!_clutter_backend_post_parse (backend, error))
|
||||||
return CLUTTER_INIT_ERROR_BACKEND;
|
return CLUTTER_INIT_ERROR_BACKEND;
|
||||||
|
|
||||||
/* Stage will give us a GL Context etc */
|
/* this will create the GL context and query it for features and
|
||||||
stage = clutter_stage_get_default ();
|
* state setup
|
||||||
if (!stage)
|
*/
|
||||||
{
|
|
||||||
if (error)
|
|
||||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
|
||||||
CLUTTER_INIT_ERROR_INTERNAL,
|
|
||||||
"Unable to create the default stage");
|
|
||||||
else
|
|
||||||
g_critical ("Unable to create the default stage");
|
|
||||||
|
|
||||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
clutter_stage_set_title (CLUTTER_STAGE (stage), g_get_prgname ());
|
|
||||||
|
|
||||||
clutter_actor_realize (stage);
|
|
||||||
|
|
||||||
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
|
||||||
{
|
|
||||||
if (error)
|
|
||||||
g_set_error (error, CLUTTER_INIT_ERROR,
|
|
||||||
CLUTTER_INIT_ERROR_INTERNAL,
|
|
||||||
"Unable to realize the default stage");
|
|
||||||
else
|
|
||||||
g_critical ("Unable to realize the default stage");
|
|
||||||
|
|
||||||
return CLUTTER_INIT_ERROR_INTERNAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now we can safely assume we have a valid GL context and can
|
|
||||||
* start issueing cogl commands
|
|
||||||
*/
|
|
||||||
/* - will call to backend and cogl */
|
|
||||||
_clutter_feature_init ();
|
_clutter_feature_init ();
|
||||||
|
|
||||||
#ifdef CLUTTER_ENABLE_PROFILE
|
#ifdef CLUTTER_ENABLE_PROFILE
|
||||||
|
@ -1587,6 +1556,36 @@ clutter_init_real (GError **error)
|
||||||
/* Initiate event collection */
|
/* Initiate event collection */
|
||||||
_clutter_backend_init_events (ctx->backend);
|
_clutter_backend_init_events (ctx->backend);
|
||||||
|
|
||||||
|
/* Create the default stage and realize it */
|
||||||
|
stage = clutter_stage_get_default ();
|
||||||
|
if (!stage)
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||||
|
CLUTTER_INIT_ERROR_INTERNAL,
|
||||||
|
"Unable to create the default stage");
|
||||||
|
else
|
||||||
|
g_critical ("Unable to create the default stage");
|
||||||
|
|
||||||
|
return CLUTTER_INIT_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_stage_set_title (CLUTTER_STAGE (stage), g_get_prgname ());
|
||||||
|
|
||||||
|
clutter_actor_realize (stage);
|
||||||
|
|
||||||
|
if (!CLUTTER_ACTOR_IS_REALIZED (stage))
|
||||||
|
{
|
||||||
|
if (error)
|
||||||
|
g_set_error (error, CLUTTER_INIT_ERROR,
|
||||||
|
CLUTTER_INIT_ERROR_INTERNAL,
|
||||||
|
"Unable to realize the default stage");
|
||||||
|
else
|
||||||
|
g_critical ("Unable to realize the default stage");
|
||||||
|
|
||||||
|
return CLUTTER_INIT_ERROR_INTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
clutter_is_initialized = TRUE;
|
clutter_is_initialized = TRUE;
|
||||||
ctx->is_initialized = TRUE;
|
ctx->is_initialized = TRUE;
|
||||||
|
|
||||||
|
|
|
@ -332,8 +332,8 @@ clutter_stage_realize (ClutterActor *self)
|
||||||
*/
|
*/
|
||||||
if (is_realized)
|
if (is_realized)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
|
||||||
ClutterBackend *backend = clutter_get_default_backend ();
|
ClutterBackend *backend = clutter_get_default_backend ();
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
/* We want to select the context without calling
|
/* We want to select the context without calling
|
||||||
clutter_backend_ensure_context so that it doesn't call any
|
clutter_backend_ensure_context so that it doesn't call any
|
||||||
|
@ -345,8 +345,8 @@ clutter_stage_realize (ClutterActor *self)
|
||||||
/* Make sure Cogl can support the driver */
|
/* Make sure Cogl can support the driver */
|
||||||
if (!_cogl_check_driver_valid (&error))
|
if (!_cogl_check_driver_valid (&error))
|
||||||
{
|
{
|
||||||
g_warning ("The GL driver is not supported: %s",
|
g_critical ("The GL driver is not supported: %s",
|
||||||
error->message);
|
error->message);
|
||||||
g_clear_error (&error);
|
g_clear_error (&error);
|
||||||
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED);
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,6 +164,9 @@ batch_and_call (CoglJournalEntry *entries,
|
||||||
int batch_len = 1;
|
int batch_len = 1;
|
||||||
CoglJournalEntry *batch_start = entries;
|
CoglJournalEntry *batch_start = entries;
|
||||||
|
|
||||||
|
if (n_entries < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 1; i < n_entries; i++)
|
for (i = 1; i < n_entries; i++)
|
||||||
{
|
{
|
||||||
CoglJournalEntry *entry0 = &entries[i - 1];
|
CoglJournalEntry *entry0 = &entries[i - 1];
|
||||||
|
|
|
@ -230,24 +230,67 @@ check_vblank_env (const char *name)
|
||||||
static ClutterFeatureFlags
|
static ClutterFeatureFlags
|
||||||
clutter_backend_glx_get_features (ClutterBackend *backend)
|
clutter_backend_glx_get_features (ClutterBackend *backend)
|
||||||
{
|
{
|
||||||
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend);
|
ClutterBackendGLX *backend_glx = CLUTTER_BACKEND_GLX (backend);
|
||||||
const gchar *glx_extensions = NULL;
|
ClutterBackendX11 *backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||||
|
const gchar *glx_extensions = NULL;
|
||||||
ClutterFeatureFlags flags;
|
ClutterFeatureFlags flags;
|
||||||
|
Window dummy_xwin, root_xwin;
|
||||||
|
XSetWindowAttributes attrs;
|
||||||
|
XVisualInfo *xvisinfo;
|
||||||
|
Display *xdisplay;
|
||||||
|
|
||||||
flags = clutter_backend_x11_get_features (backend);
|
flags = clutter_backend_x11_get_features (backend);
|
||||||
flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
|
flags |= CLUTTER_FEATURE_STAGE_MULTIPLE;
|
||||||
|
|
||||||
/* this will make sure that the GL context exists and
|
/* this will make sure that the GL context exists */
|
||||||
* it's bound to a drawable
|
|
||||||
*/
|
|
||||||
g_assert (backend_glx->gl_context != None);
|
g_assert (backend_glx->gl_context != None);
|
||||||
g_assert (glXGetCurrentDrawable () != None);
|
|
||||||
|
|
||||||
CLUTTER_NOTE (BACKEND, "Checking features\n"
|
/* in order to query the GL and GLX implementation we
|
||||||
"GL_VENDOR: %s\n"
|
* need to bind the GLX context to a Drawable; we create
|
||||||
"GL_RENDERER: %s\n"
|
* a simple, off-screen override-redirect window that we
|
||||||
"GL_VERSION: %s\n"
|
* then destroy at the end of this function
|
||||||
"GL_EXTENSIONS: %s\n",
|
*/
|
||||||
|
xdisplay = clutter_x11_get_default_display ();
|
||||||
|
root_xwin = clutter_x11_get_root_window ();
|
||||||
|
|
||||||
|
xvisinfo = clutter_backend_x11_get_visual_info (backend_x11);
|
||||||
|
if (xvisinfo == None)
|
||||||
|
{
|
||||||
|
g_critical ("Unable to retrieve the X11 visual");
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
clutter_x11_trap_x_errors ();
|
||||||
|
|
||||||
|
attrs.override_redirect = True;
|
||||||
|
attrs.colormap = XCreateColormap (xdisplay, root_xwin,
|
||||||
|
xvisinfo->visual,
|
||||||
|
AllocNone);
|
||||||
|
dummy_xwin = XCreateWindow (xdisplay, root_xwin,
|
||||||
|
-100, -100, 1, 1,
|
||||||
|
0,
|
||||||
|
xvisinfo->depth,
|
||||||
|
CopyFromParent,
|
||||||
|
xvisinfo->visual,
|
||||||
|
CWOverrideRedirect | CWColormap,
|
||||||
|
&attrs);
|
||||||
|
|
||||||
|
glXMakeContextCurrent (xdisplay,
|
||||||
|
dummy_xwin, dummy_xwin,
|
||||||
|
backend_glx->gl_context);
|
||||||
|
|
||||||
|
if (clutter_x11_untrap_x_errors ())
|
||||||
|
{
|
||||||
|
g_critical ("Unable to retrieve the GLX features");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLUTTER_NOTE (BACKEND,
|
||||||
|
"Checking features\n"
|
||||||
|
" GL_VENDOR: %s\n"
|
||||||
|
" GL_RENDERER: %s\n"
|
||||||
|
" GL_VERSION: %s\n"
|
||||||
|
" GL_EXTENSIONS: %s\n",
|
||||||
glGetString (GL_VENDOR),
|
glGetString (GL_VENDOR),
|
||||||
glGetString (GL_RENDERER),
|
glGetString (GL_RENDERER),
|
||||||
glGetString (GL_VERSION),
|
glGetString (GL_VERSION),
|
||||||
|
@ -260,7 +303,7 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
|
||||||
CLUTTER_NOTE (BACKEND, "GLX Extensions: %s", glx_extensions);
|
CLUTTER_NOTE (BACKEND, "GLX Extensions: %s", glx_extensions);
|
||||||
|
|
||||||
/* First check for explicit disabling or it set elsewhere (eg NVIDIA) */
|
/* First check for explicit disabling or it set elsewhere (eg NVIDIA) */
|
||||||
if (getenv("__GL_SYNC_TO_VBLANK") || check_vblank_env ("none"))
|
if (getenv ("__GL_SYNC_TO_VBLANK") || check_vblank_env ("none"))
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (BACKEND, "vblank sync: disabled at user request");
|
CLUTTER_NOTE (BACKEND, "vblank sync: disabled at user request");
|
||||||
}
|
}
|
||||||
|
@ -277,7 +320,7 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
|
||||||
* How well glXGetVideoSyncSGI works with other driver (ATI etc) needs
|
* How well glXGetVideoSyncSGI works with other driver (ATI etc) needs
|
||||||
* to be investigated. glXGetVideoSyncSGI on ATI at least seems to have
|
* to be investigated. glXGetVideoSyncSGI on ATI at least seems to have
|
||||||
* no effect.
|
* no effect.
|
||||||
*/
|
*/
|
||||||
if (!check_vblank_env ("dri") &&
|
if (!check_vblank_env ("dri") &&
|
||||||
cogl_check_extension ("GLX_SGI_swap_control", glx_extensions))
|
cogl_check_extension ("GLX_SGI_swap_control", glx_extensions))
|
||||||
{
|
{
|
||||||
|
@ -325,10 +368,11 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
|
||||||
if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK))
|
if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK))
|
||||||
CLUTTER_NOTE (BACKEND, "glXGetVideoSyncSGI vblank setup failed");
|
CLUTTER_NOTE (BACKEND, "glXGetVideoSyncSGI vblank setup failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
/*
|
/*
|
||||||
* DRI is really an extreme fallback -rumoured to work with Via chipsets
|
* DRI is really an extreme fallback -rumoured to work with Via chipsets
|
||||||
*/
|
*/
|
||||||
if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK))
|
if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK))
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (BACKEND, "attempting DRI vblank setup");
|
CLUTTER_NOTE (BACKEND, "attempting DRI vblank setup");
|
||||||
|
@ -344,14 +388,19 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
|
||||||
CLUTTER_NOTE (BACKEND, "DRI vblank setup failed");
|
CLUTTER_NOTE (BACKEND, "DRI vblank setup failed");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK))
|
if (!(flags & CLUTTER_FEATURE_SYNC_TO_VBLANK))
|
||||||
{
|
CLUTTER_NOTE (BACKEND, "no use-able vblank mechanism found");
|
||||||
CLUTTER_NOTE (BACKEND,
|
|
||||||
"no use-able vblank mechanism found");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CLUTTER_NOTE (MISC, "backend features checked");
|
CLUTTER_NOTE (BACKEND, "backend features checked");
|
||||||
|
|
||||||
|
out:
|
||||||
|
/* unset the GLX context */
|
||||||
|
glXMakeContextCurrent (xdisplay, None, None, NULL);
|
||||||
|
|
||||||
|
/* destroy the dummy Window */
|
||||||
|
XDestroyWindow (xdisplay, dummy_xwin);
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
@ -542,15 +591,16 @@ clutter_backend_glx_ensure_context (ClutterBackend *backend,
|
||||||
|
|
||||||
g_assert (impl != NULL);
|
g_assert (impl != NULL);
|
||||||
|
|
||||||
CLUTTER_NOTE (MULTISTAGE, "Setting context for stage of type %s [%p]",
|
|
||||||
g_type_name (G_OBJECT_TYPE (impl)),
|
|
||||||
impl);
|
|
||||||
|
|
||||||
stage_glx = CLUTTER_STAGE_GLX (impl);
|
stage_glx = CLUTTER_STAGE_GLX (impl);
|
||||||
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
stage_x11 = CLUTTER_STAGE_X11 (impl);
|
||||||
backend_glx = CLUTTER_BACKEND_GLX (backend);
|
backend_glx = CLUTTER_BACKEND_GLX (backend);
|
||||||
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
backend_x11 = CLUTTER_BACKEND_X11 (backend);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (BACKEND,
|
||||||
|
"Setting context for stage of type %s, window: 0x%x",
|
||||||
|
G_OBJECT_TYPE_NAME (impl),
|
||||||
|
(int) stage_x11->xwin);
|
||||||
|
|
||||||
/* no GL context to set */
|
/* no GL context to set */
|
||||||
if (backend_glx->gl_context == None)
|
if (backend_glx->gl_context == None)
|
||||||
return;
|
return;
|
||||||
|
@ -562,7 +612,7 @@ clutter_backend_glx_ensure_context (ClutterBackend *backend,
|
||||||
*/
|
*/
|
||||||
if (stage_x11->xwin == None)
|
if (stage_x11->xwin == None)
|
||||||
{
|
{
|
||||||
CLUTTER_NOTE (MULTISTAGE,
|
CLUTTER_NOTE (BACKEND,
|
||||||
"Received a stale stage, clearing all context");
|
"Received a stale stage, clearing all context");
|
||||||
|
|
||||||
glXMakeContextCurrent (backend_x11->xdpy, None, None, NULL);
|
glXMakeContextCurrent (backend_x11->xdpy, None, None, NULL);
|
||||||
|
|
|
@ -135,6 +135,11 @@ clutter_stage_glx_realize (ClutterStageWindow *stage_window)
|
||||||
InputOutput,
|
InputOutput,
|
||||||
xvisinfo->visual,
|
xvisinfo->visual,
|
||||||
mask, &xattr);
|
mask, &xattr);
|
||||||
|
|
||||||
|
CLUTTER_NOTE (BACKEND, "Stage [%p], window: 0x%x",
|
||||||
|
stage_window,
|
||||||
|
(unsigned int) stage_x11->xwin);
|
||||||
|
|
||||||
XFree (xvisinfo);
|
XFree (xvisinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue