From: Olivier Andrieu MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <17217.25667.180590.634675 at karryall.dnsalias.org> Date: Mon, 3 Oct 2005 19:02:59 +0200 To: Sebastien Ferre Cc: lablgtk at math.nagoya-u.ac.jp Subject: Re: GTree: delaying the computation of a pixbuf upon visibility In-Reply-To: <43412404.3090002 at irisa.fr> References: <43355ED4.5000004 at inria.fr> <433A46AE.8000004@irisa.fr> <17211.57896.40053.753344@karryall.dnsalias.org> <433CF2BA.8030204@irisa.fr> <17215.60406.276599.274837@karryall.dnsalias.org> <4340EEAA.8060904@irisa.fr> <17217.4772.442804.374366@karryall.dnsalias.org> <43412404.3090002@irisa.fr> Sebastien Ferre [Monday 3 October 2005] : > > Olivier Andrieu wrote: > > Sebastien Ferre [Monday 3 October 2005] : > > > > > > Olivier Andrieu wrote: > > > > Sebastien Ferre [Friday 30 September 2005] : > > > > > > > > > > Hi, > > > > > > > > > > Olivier Andrieu wrote: > > > > > > Sebastien Ferre [Wednesday 28 September 2005] : > > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > I'm working on a GUI in which there is a > > > > > > > 'GTree.list_store' of thumbnails (look at > > > > > > > http://www.irisa.fr/lande/ferre/camelis for screen > > > > > > > captions). I use the library CamlImages for > > > > > > > computing these thumbnails from JPEG pictures. > > > > > > > > > > > > Why don't you use GdkPixbuf for this ? It can load JPEG > > > > > > pictures. > > > > > > > > > > this is what I used at the beginning. But I noticed there > > > > > was something like a memory leak as the process rapidly > > > > > grew to more than 1Gb of memory, while I checked the > > > > > loaded images were no more reachable. > > > > > > > > Ah. It might be a memory leak in lablgtk. I'd be interested > > > > if you still have some code showing this problem. > > > > > > If you call many times the function 'pixmap_of_picture', you > > > should exhibit the problem. It seems the data in local > > > variable 'pixbuf' is never deallocated (while the use of > > > Gc.finalize shows it do become unreachable, as expected). > > > > Argl. OK I remember: indeed GdkPixbuf.from_file had a leak in > > lablgtk 2.4.0 (the pixbuf was referenced before being returned to > > caml and thus never deallocated). I fixed this in the first > > snapshot after lablgtk 2.4.0 (2004-11-19). But later, when I > > added support for serialisation of GdkPixbufs, I inadvertently > > broke the reference counting. This means that with the latest > > snapshot all functions creating pixbufs (like GdkPixbuf.copy, > > new_from_file, etc.) leak the pixbuf. (This will be fixed in the > > next version of course). > > > > > > > Also, CamlImages allows for loading directly a thumbnail > > > > > from JPEG pictures, which is lighter. > > > > > > > > GdkPixbuf has a GdkPixbuf.from_file_at_size function that > > > > lets you do that too (I hope so). > > > > > > I can't find it. Is it in a newer version ? (I have version > > > 2.4.0). > > > > Yes it's in newer versions. > > > > So, could you do this: > > > > - download the lastest lablgtk snapshot > > http://wwwfun.kurims.kyoto-u.ac.jp/soft/olabl/dist/lablgtk2-20050701.tar.gz > > - apply the attached patch to fix the pixbuf refcounting > > - compile, install > > - test your program with GdkPixbuf.new_from_file/GdkPixbuf.scale : it > > shouldn't leak anymore > > - test your program with GdkPixbuf.new_from_file_at_size > > Great! there is no more memory leak, in both cases. And the > solution with 'from_file_at_size' is much quicker. > > There is only one last thing that is annoying, while not so > important. It is that even if a few pictures are displayed in the > list_store, it is not possible to select them while other pictures > are computed (with Glib.Idle) and displayed. Do you have any hint > on that subject ? How are you using the idle callback exactly ? The idea is to compute just one thumbnail (or a small fixed number) in the callback and reschedule it so that the program re-enters the main loop and handles events that occured during the idle callback. Something like this: let do_while_idle : (unit -> unit) Queue.t -> Glib.Idle.id = fun q -> Glib.Idle.add (fun () -> try Queue.take q () ; true with Queue.Empty -> false) -- Olivier