Re: Building multiple backends on on same system



Alexander Larsson <alexl <at> redhat.com> writes:
> Support specifying multiple targets in --with-gdktarget, then build a
> single libgtk-3.0.so supporting all of these, switching at runtime. At
> one time i was thinking we could load the backends dynamically to avoid
> linking to all the dependencies of all backends, but since cairo links
> in all backends in the same library anyway this will not work.
> 
I suppose you're targetting something similar to Cairo? So that you can query 
the backend of a GdkWindow or GdkVisual or GdkDisplay at runtime? And when 
starting the application you pick a certain default backend?

> We then have a gtk+-3.0.pc file that does not pull in any backend
> libraries (like xlib) into the app. The we add e.g. gtk+-x11-3.0 that
> contains the backend specific headers like gdkx.h, the backend libraries
> and headers. This file would be installed only if gtk+ was built with X
> support of course.
> 
or we'd do it like Cairo and uild all of them into libgtk.so. But that's a 
detail I don't particularly care about. The only important thing is that 
libgtk knows what the default backend to is and has a way to use it.

> Then we take the current internal defines like GDK_WINDOWING_X11 and put
> the supported ones in a public header, so that apps can build
> conditional backend support. Additionally we now allow multiple of these
> to be defined in the same build.
> 
> Then we add a GdkBackend type that each backend implements. This is a
> singleton created at init to hang global stuff off. Its also useful for
> backend specific code. For instance:
> 
> #ifdef GDK_WINDOWING_X11
>   if (timestamp != GDK_CURRENT_TIME)
>     gdk_x11_window_set_user_time (gdk_window, timestamp);
> #endif
> 
> Will turn into:
> 
> #ifdef GDK_WINDOWING_X11
>    if (GDK_IS_BACKEND_X11 (gdk_backend_get ()))
>      {
>       if (timestamp != GDK_CURRENT_TIME)
> 	gdk_x11_window_set_user_time (gdk_window, timestamp);
>      }
> #endif
> 
I would make that part of the GdkDisplay, as that pretty much is our 
current singleton. So you'd do something like:

#ifdef GDK_WINDOWING_X11
  if (GDK_IS_X11_DISPLAY (display))
    {
      if (timestamp != GDK_CURRENT_TIME)
        gdk_x11_window_set_user_time (gdk_window, timestamp);
    }
#endif

> Additionally, I think we should drop libgdk.so and just combine the two
> into one. There are no users of gdk without gtk anyway, and gtk has
> backend specific code in it anyway, so gdk is not a full abstraction.
> This will get us one less library, plus it will make all gdk calls from
> gtk+ intra-object calls which is a (minor) performance gain.
> 
I do like the split conceptually, because it forces us to define a sane 
interface between GTK and the backends. But I guess as long as we keep 
stuff in seperate directories and make sure to not let GTK use private APIs 
(as it currently does in the configure event trickery ;)) we'll be fine and 
it doesn't matter if we use noinst_LTLIBRIRES or lib_LTLIBRARIES for libgdk.

> * Hide the class structs for all backend-implemented object types
> (GdkDisplay, GdkDevice, etc) to let us change the internals later.
> 
We should do this anyway.

> * Convert all backend object method calls to true vtable calls, rather
> than have the linker pick the right one. (For instance,
> gdk_device_ungrab() is right now duplicated in each backend, and relies
> on the linker to pick the one from the backend you link with. Obviously
> this will not work in a multi-backend scenario, instead we need a single
> gdk_device_ungrab() call in the common code that does a vcall on the
> GdkDevice class.)
> 
I somewhat disagree on this one. At least in the case of GdkWindow do we have 
a sane abstraction in the form of GdkWindowImpl already that we can put into 
the backend. So making all GdkWindow APIs vfuncs doesn't sound like that 
awesome of an idea to me. For most the other types, we need to add more vfuncs 
though.

> * Convert GdkCursor to a GObject so we get a class vtable
> 
That should have been done ages ago. Will do that now.

> * (Optionally) move code common to all backends (for instance,  
>   typechecks, etc) from the backend code to the common code that does
>   the vtable call.
>
I'd go the other way and move code into backends only when it can't stay in 
the core implementation. Otherwise we'll end up with lots of duplications 
again. And I just worked hard to get rid of that...
 
> * Add a GdkBackend type, derive from this in all backends
> 
See my comment above about using GdkDisplay for that.

> * Convert all global functions (both external and gdk internal ones) in
>   the backend to vtable calls on the backend object.
> 
Do we have lots of those? I mean functions that differ between backends and 
don't take some sort of GObject as an argument? Could we hang them off 
GdkDisplay?


Also, do you target this for 3.0? Because I don't think it's doable in an 
API-stable way during 3.x?

Benjamin



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]