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]

Reply via email to