Re: [clutter] RFC: Are toggle references needed for CoglHandle ?



Hi,

Sorry for the time warp, I was just looking at clutter master and
trying to figure out the story on CoglHandle. I stumbled on this
thread looking for the thread about "why not GTypeInstance?" (this
thread exists, surely ;-)

I think toggle refs are necessary unless you want to live with the "N
proxies per native object" issue. The traditional rule is that objects
need to be one of:
 * value objects (can be copied by value / have value semantics)
 * or GObject (reference semantics)

to be binding-friendly. GObject of course really means "has user data,
toggle refs, etc." but any GObject-like thing is a pile of tricky code
for bindings (and the GObject-like thing) so using GObject itself is
always preferred obviously.

There's a special case of "immutable objects with refcount" which can
be treated as copy-on-write value objects that are never written. N
proxies are fine here.

The original toggle refs mail says they were added for Java and CLR
(which are not the simple mark-and-sweep gc):
http://mail.gnome.org/archives/gtk-devel-list/2005-April/msg00095.html

spidermonkey (gjs) is mark and sweep now, but I think may not be in
the fancy new fast versions.

I'd guess most bindings for cairo and GstMiniObject basically just
punt and have N proxies per native object. The semantics of those
particular domains makes it probably OK, where it would be
super-painful for say ClutterActor or GtkWidget if you couldn't set a
Ruby or JS or Python property on those objects and expect it to
"stick." A cairo_t is normally created and tossed in one repaint and
not ever saved.

For some types, such as cairo_surface_t, it kind of sucks to have N
proxies, though. Especially with cairo_surface_t now replacing
gdk-pixbuf.

GStreamer has GObjects also, making a distinction between some sort of
"transient, must be fast" objects and "more heavy API objects" (I
don't know how they'd describe it) but e.g. GstElement is a full
GObject and that's the main app API.

This model might be a good one for cogl - try to distinguish between
things that need to be light and throwaway and things the app might
legitimately want to keep around, set properties on, etc. And use
GObject for more "persistent" types.

Havoc

On Tue, Jun 8, 2010 at 8:41 AM, Neil Roberts <neil linux intel com> wrote:
> Hi
>
> I've started looking at the Ruby bindings for Clutter and I was
> wondering about how best to bind CoglHandles. Currently they are just
> wrapped as a boxed type. This has the effect that every time you query a
> property that is a CoglHandle then the result appears as a completely
> new object to the eyes of the interpreter. For example:
>
> # This creates a new ClutterTexture
> irb(main):003:0> tex = Clutter::Texture.new("redhand.png")
> => #<Clutter::Texture:0x86070c0 ptr=0x86580a8>
>
> # This queries the 'cogl_texture' property which returns the boxed
> # CoglHandle.
> irb(main):005:0> handle1 = tex.cogl_texture
> => #<Cogl::Texture:0x85d8190 ptr=0x8649db8 own=true>
>
> # If we query it a second time we can see that we've got a different
> # object
> irb(main):006:0> handle2 = tex.cogl_texture
> => #<Cogl::Texture:0x85d4610 ptr=0x8649db8 own=true>
> irb(main):008:0> handle1.object_id
> => 70172872
> irb(main):009:0> handle2.object_id
> => 70165256
>
> This isn't a major problem but it does mean that you can't attach data
> to the Ruby object or subclass it and expect it to survive if you set it
> as a property. Eg:
>
> # Create a new Cogl texture
> irb(main):010:0> handle = Cogl::Texture.new("redhand.png")
> => #<Cogl::Texture:0x85c574c ptr=0x86400b8 own=true>
>
> # Set some data on it
> irb(main):021:0> handle.instance_variable_set(:@some_data, [1,2,3])
> => [1, 2, 3]
>
> # Put it in the ClutterTexture
> irb(main):023:0> tex.cogl_texture = handle
> => #<Cogl::Texture:0x85c574c ptr=0x86400b8 own=true>
>
> # If we query it back out then the data is lost
> irb(main):024:0> tex.cogl_texture.instance_variable_get(:@some_data)
> => nil
>
> Recently Cogl in git has gained support for attaching arbitrary user
> data to any handle using a pointer as a key in much the same way as
> Cairo does. We could use this to attach the Ruby proxy object to the
> handle so that it could return the same object every time the handle is
> seen. However if we do this then we need to resolve the issue that both
> the proxy object and the GObject will need to reference each other yet
> we still want them to be garbage collected. Most languages that bind
> GObject seem to use toggle references to fix this. So my question is,
> should we add toggle reference support to CoglHandles?
>
> I think for languages with a mark-sweep garbage collector (like Ruby) we
> could get away without toggle references if the reference count on the
> handle was publicly visible. I would imagine you would then need to
> store a list of all GObjects that Ruby has ever seen and then during the
> mark phase you simply need to walk the list and mark any objects that
> have a ref count > 1 (meaning something in GLib-land is also using the
> object). However my hunch is that this isn't sufficient for languages
> that use ref-counting for their own garbage collection because then
> there'd be no equivalent of the mark phase.
>
> CoglHandles are pretty similar to GstMiniObjects and cairo's object
> system as far as I can tell. How is binding handled for those? As far as
> I can tell for cairo Python just creates a new wrapper object each time:
>
>>>> surface = cairo.SVGSurface('out.svg', 100, 100)
>>>> cr = cairo.Context(surface)
>>>> source1 = cr.get_source()
>>>> source2 = cr.get_source()
>>>> id(source1)
> 3078983840L
>>>> id(source2)
> 3078983856L
>
> Ruby seems to use Cairo's user data retain the proxy object, but looking
> at the code I can't work out why this doesn't cause a leak (maybe it
> does).
>
> irb(main):002:0> surface = Cairo::SVGSurface.new('out.svg', 100, 100)
> => #<Cairo::SVGSurface:0xb764ce4c>
> irb(main):003:0> cr = Cairo::Context.new(surface)
> => #<Cairo::Context:0xb764a228>
> irb(main):004:0> source1 = cr.source
> => #<Cairo::SolidPattern:0xb7648270>
> irb(main):005:0> source2 = cr.source
> => #<Cairo::SolidPattern:0xb7648270>
> irb(main):006:0> source1.object_id
> => -609074888
> irb(main):007:0> source2.object_id
> => -609074888
>
> Both cairo and GstMiniObject publicly expose the ref count. Would this
> be enough for bindings?
>
> Any help is much appreciated.
>
> Regards,
> - Neil
> --
> To unsubscribe send a mail to clutter+unsubscribe o-hand com
>
>


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