diff --git a/ChangeLog b/ChangeLog index fc610e283..cf97d036c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2008-04-04 Emmanuele Bassi + + * clutter/clutter-backend.c: Add more debug messages + + * clutter/clutter-stage.h: + * clutter/clutter-stage.c: + (clutter_stage_is_default): Add a function to check if the + stage is the default one. + + * clutter/glx/clutter-backend-glx.c: + * clutter/glx/clutter-stage-glx.c: + * clutter/x11/clutter-stage-x11.c: Keep the stage wrapper + and implementation flags in sync, to ensure that the GL + context is always set. + 2008-04-04 Neil Roberts * README: Fixed typo diff --git a/clutter/clutter-backend.c b/clutter/clutter-backend.c index 4c259dd87..bb6209147 100644 --- a/clutter/clutter-backend.c +++ b/clutter/clutter-backend.c @@ -189,13 +189,15 @@ _clutter_backend_ensure_context (ClutterBackend *backend, g_return_if_fail (CLUTTER_IS_BACKEND (backend)); g_return_if_fail (CLUTTER_IS_STAGE (stage)); - if (stage != current_context_stage || !CLUTTER_ACTOR_IS_REALIZED (stage)) + if (current_context_stage != stage || !CLUTTER_ACTOR_IS_REALIZED (stage)) { if (!CLUTTER_ACTOR_IS_REALIZED (stage)) { - CLUTTER_NOTE (MULTISTAGE, "Stage is not realized"); + CLUTTER_NOTE (MULTISTAGE, "Stage is not realized, unsetting"); stage = NULL; } + else + CLUTTER_NOTE (MULTISTAGE, "Setting the new stage [%p]", stage); klass = CLUTTER_BACKEND_GET_CLASS (backend); if (G_LIKELY (klass->ensure_context)) @@ -205,13 +207,14 @@ _clutter_backend_ensure_context (ClutterBackend *backend, * sense to clean the context but then re call with the default stage * so at least there is some kind of context in place (as to avoid * potential issue of GL calls with no context) - */ - + */ current_context_stage = stage; if (stage) CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_ACTOR_SYNC_MATRICES); } + else + CLUTTER_NOTE (MULTISTAGE, "Stage is the same"); } diff --git a/clutter/clutter-stage.c b/clutter/clutter-stage.c index 7b71686d3..cb9e208bb 100644 --- a/clutter/clutter-stage.c +++ b/clutter/clutter-stage.c @@ -188,11 +188,14 @@ clutter_stage_realize (ClutterActor *self) ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv; /* then realize the implementation */ + g_assert (priv->impl != NULL); CLUTTER_ACTOR_GET_CLASS (priv->impl)->realize (priv->impl); /* set the flag on the wrapper if the implementation was successful */ if (CLUTTER_ACTOR_IS_REALIZED (priv->impl)) CLUTTER_ACTOR_SET_FLAGS (self, CLUTTER_ACTOR_REALIZED); + else + CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED); } static void @@ -204,6 +207,7 @@ clutter_stage_unrealize (ClutterActor *self) CLUTTER_ACTOR_UNSET_FLAGS (self, CLUTTER_ACTOR_REALIZED); /* and then unrealize the implementation */ + g_assert (priv->impl != NULL); CLUTTER_ACTOR_GET_CLASS (priv->impl)->unrealize (priv->impl); } @@ -1665,6 +1669,34 @@ clutter_stage_queue_redraw (ClutterStage *stage) } } +/** + * clutter_stage_is_default: + * @stage: a #ClutterStage + * + * Checks if @stage is the default stage, or an instance created using + * clutter_stage_new() but internally using the same implementation. + * + * Return value: %TRUE if the passed stage is the default one + * + * Since: 0.8 + */ +gboolean +clutter_stage_is_default (ClutterStage *stage) +{ + ClutterStageWindow *impl; + + g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); + + if (CLUTTER_ACTOR (stage) == clutter_stage_get_default ()) + return TRUE; + + impl = _clutter_stage_get_window (stage); + if (impl == _clutter_stage_get_default_window ()) + return TRUE; + + return FALSE; +} + void _clutter_stage_set_window (ClutterStage *stage, ClutterStageWindow *stage_window) diff --git a/clutter/clutter-stage.h b/clutter/clutter-stage.h index eeb8ec4c8..ff2954f86 100644 --- a/clutter/clutter-stage.h +++ b/clutter/clutter-stage.h @@ -227,6 +227,7 @@ ClutterActor * clutter_stage_get_key_focus (ClutterStage *stage); /* New experiental calls */ void clutter_stage_ensure_current (ClutterStage *stage); void clutter_stage_queue_redraw (ClutterStage *stage); +gboolean clutter_stage_is_default (ClutterStage *stage); /* Commodity macro */ #define clutter_stage_add(stage,actor) G_STMT_START { \ diff --git a/clutter/glx/clutter-backend-glx.c b/clutter/glx/clutter-backend-glx.c index f612413e3..58a7eb2cb 100644 --- a/clutter/glx/clutter-backend-glx.c +++ b/clutter/glx/clutter-backend-glx.c @@ -390,7 +390,9 @@ clutter_backend_glx_ensure_context (ClutterBackend *backend, stage_x11 = CLUTTER_STAGE_X11 (impl); backend_glx = CLUTTER_BACKEND_GLX (backend); - g_return_if_fail (backend_glx->gl_context != None); + /* no GL context to set */ + if (backend_glx->gl_context == None) + return; /* we might get here inside the final dispose cycle, so we * need to handle this gracefully @@ -406,9 +408,18 @@ clutter_backend_glx_ensure_context (ClutterBackend *backend, glXMakeCurrent (backend_x11->xdpy, None, NULL); } else - glXMakeCurrent (stage_x11->xdpy, - stage_x11->xwin, + { + CLUTTER_NOTE (BACKEND, + "MakeCurrent dpy: %p, window: 0x%x (%s), context: %p", + stage_x11->xdpy, + (int) stage_x11->xwin, + stage_x11->is_foreign_xwin ? "foreign" : "native", backend_glx->gl_context); + + glXMakeCurrent (stage_x11->xdpy, + stage_x11->xwin, + backend_glx->gl_context); + } } } diff --git a/clutter/glx/clutter-stage-glx.c b/clutter/glx/clutter-stage-glx.c index 82b174a8d..d25b9625d 100644 --- a/clutter/glx/clutter-stage-glx.c +++ b/clutter/glx/clutter-stage-glx.c @@ -65,7 +65,7 @@ clutter_stage_glx_unrealize (ClutterActor *actor) gboolean was_offscreen; /* Note unrealize should free up any backend stage related resources */ - CLUTTER_MARK(); + CLUTTER_NOTE (BACKEND, "Unrealizing stage"); g_object_get (stage_x11->wrapper, "offscreen", &was_offscreen, NULL); @@ -155,8 +155,6 @@ clutter_stage_glx_realize (ClutterActor *actor) if (!stage_x11->xvisinfo) { g_critical ("Unable to find suitable GL visual."); - - CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED); CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED); return; } @@ -204,27 +202,26 @@ clutter_stage_glx_realize (ClutterActor *actor) clutter_stage_x11_fix_window_size (stage_x11); clutter_stage_x11_set_wm_protocols (stage_x11); - if (backend_glx->gl_context == None) + if (G_UNLIKELY (backend_glx->gl_context == None)) { CLUTTER_NOTE (GL, "Creating GL Context"); - backend_glx->gl_context = glXCreateContext (stage_x11->xdpy, - stage_x11->xvisinfo, - 0, - True); + backend_glx->gl_context = glXCreateContext (stage_x11->xdpy, + stage_x11->xvisinfo, + 0, + True); if (backend_glx->gl_context == None) { g_critical ("Unable to create suitable GL context."); - - CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED); CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED); - return; } } - CLUTTER_NOTE (GL, "glXMakeCurrent"); + /* this will make sure to set the current context */ + CLUTTER_NOTE (BACKEND, "Marking stage as realized and setting context"); CLUTTER_ACTOR_SET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED); + CLUTTER_ACTOR_SET_FLAGS (stage_x11, CLUTTER_ACTOR_REALIZED); clutter_stage_ensure_current (stage_x11->wrapper); } else @@ -286,7 +283,7 @@ clutter_stage_glx_realize (ClutterActor *actor) g_critical ("Unable to create suitable GL context."); CLUTTER_ACTOR_UNSET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED); - CLUTTER_ACTOR_UNSET_FLAGS (actor, CLUTTER_ACTOR_REALIZED); + CLUTTER_ACTOR_UNSET_FLAGS (stage_x11, CLUTTER_ACTOR_REALIZED); return; } @@ -295,6 +292,8 @@ clutter_stage_glx_realize (ClutterActor *actor) clutter_x11_trap_x_errors (); /* below will call glxMakeCurrent */ + CLUTTER_ACTOR_SET_FLAGS (stage_x11->wrapper, CLUTTER_ACTOR_REALIZED); + CLUTTER_ACTOR_SET_FLAGS (stage_x11, CLUTTER_ACTOR_REALIZED); clutter_stage_ensure_current (stage_x11->wrapper); if (clutter_x11_untrap_x_errors ()) diff --git a/clutter/x11/clutter-stage-x11.c b/clutter/x11/clutter-stage-x11.c index c0d945ded..8076e71f5 100644 --- a/clutter/x11/clutter-stage-x11.c +++ b/clutter/x11/clutter-stage-x11.c @@ -578,14 +578,14 @@ clutter_x11_set_stage_foreign (ClutterStage *stage, g_return_val_if_fail (CLUTTER_IS_STAGE (stage), FALSE); g_return_val_if_fail (xwindow != None, FALSE); + actor = CLUTTER_ACTOR (stage); + impl = _clutter_stage_get_window (stage); stage_x11 = CLUTTER_STAGE_X11 (impl); - actor = CLUTTER_ACTOR (impl); clutter_x11_trap_x_errors (); - status = XGetGeometry (stage_x11->xdpy, - xwindow, + status = XGetGeometry (stage_x11->xdpy, xwindow, &root_return, &x, &y, &width, &height, @@ -597,11 +597,14 @@ clutter_x11_set_stage_foreign (ClutterStage *stage, width == 0 || height == 0 || depth != stage_x11->xvisinfo->depth) { + g_warning ("Unable to retrieve the new window geometry"); return FALSE; } clutter_actor_unrealize (actor); + CLUTTER_NOTE (BACKEND, "Setting foreign window (0x%x)", (int) xwindow); + stage_x11->xwin = xwindow; stage_x11->is_foreign_xwin = TRUE;