Hi, I've just ported the OSX backend to r 2612 (see bug 911) and noticed there's this document explaining how it should've been done :) Here's some comments about HACKING.backends.
It's very useful in explaining some of the obscure details and expectations you wouldn't otherwise know. However the relationship between the wrapper and implementation is not entirely clear on clean, there's quite a big difference between how realize+unrealize is to be implemented compared to show+hide. I think the biggest problem is that the backend needs to concern too much about keeping the wrapper state in sync rather than the wrapper following the backend. Some more details below: > ClutterBackend::create_stage > -- This function is used to create the stage implementation. It will > receive as an argument the ClutterStage instance that is "wrapping" > the actual implementation being created. The backend must create > its stage implementation and call _clutter_stage_set_window() with > the wrapper and the stage implementation instance: > > _clutter_stage_set_window (wrapper, CLUTTER_STAGE_WINDOW (impl)); > > The backend must also call clutter_actor_realize() on the stage > implementation, Err, why the backend? Also as realize is expected to set the new stage current, isn't this making a mess of any context management? > and then check if the stage has been realized, using > the CLUTTER_ACTOR_IS_REALIZED() macro; if the stage was not > realized, it must return NULL and set the passed GError. Again, why in the backend? Might be worth noting that this leaves the wrapper in inconsistent state as a result of previous call to _clutter_stage_set_window() -- the stage should've been destroyed by now (since, well, create failed) > Inside the ::realize function the stage implementation should: > - create the drawing context (either GL or GLES) and assign it > to the backend, if it's not already present What does 'assigning to backend' mean? That you can only have single GL context? I'm creating one GL context per stage and I am seeing rendering artefacts with text on multiple stages, so I guess so. > - set the CLUTTER_ACTOR_REALIZED flag on *both* the wrapper and the > stage implementation > - call clutter_stage_ensure_current() with the wrapper instance Why in the backend? Especially manipulating the wrapper state feels bordering silly. IMO the wrapper should forward all relevant state change from the wrapper to implementation (documentation suggests this is the case) but also mirror the resulting state from implementation back to the wrapper. Just to note, the consequence of not setting REALIZED on the wrapper resulted in realize+realize call sequence into the backend, no unrealize in between. This raises a question, which of the following is correct: 1) realize(): g_assert(!REALIZED) show(): g_assert(!MAPPED) hide(): g_assert(MAPPED) unrealize(): g_assert(REALIZED) 2) realize(): if(REALIZED) return; show(): if (MAPPED) return; hide(): if (!MAPPED) return; unrealized(): if (!REALIZED) return; Also, need / expectation to chain up to parent is rather vague. Most observant might've also noticed how the function and state are consistent for realize/REALIZED, but not for show/MAPPED. > Inside the ::unrealize function the stage implementation should: > > - unset the CLUTTER_ACTOR_REALIZED flag But not on the wrapper? What about chaining up to parent? Would it do that? > - call _clutter_shader_release_all() if the backend supports shaders > and the GL programmable pipeline Is there some call ordering constraint requiring this to be done in the backend rather than in the core / wrapper? > - destroy the native window handle > - call clutter_stage_ensure_context() with the wrapper instance Err, why? Didn't we just destroy the underlying resources, including GL context? -- Tommi Komulainen [EMAIL PROTECTED] -- To unsubscribe send a mail to [EMAIL PROTECTED]
