On 23/11/09 12:46, Axel Simon wrote:
> On Mon, 2009-11-23 at 11:01 +0000, Simon Marlow wrote:
>> Axel,  this is great news, many thanks for working on it!
>>
>> I'm interested in using Cairo from multiple threads.  What exactly is
>> supported there?  Can I run an arbitrary Render operation on any thread
>> I like?
>
> Yes, as long as you manipulate each Cairo object within one thread:
>
> http://lists.cairographics.org/archives/cairo/2009-February/016648.html
>
> However, it involves some effort to repaint a widget using a different
> thread even through you never directly paint to the screen due to Gtk's
> double buffering. The reason is that the expose event EExpose internally
> sets a Pixmap aside before the signal is emitted and will copy this
> Pixmap to the actual window once the signal handler has returned. Thus,
> you cannot spawn a thread off in the EExpose handler since it would have
> to finish before the handler can return.
>
> So I think you need to pro-actively update a Pixmap using Cairo whenever
> the content should changes. You do this in its own thread using
> renderWithDrawable. Whenever the the new Pixmap is ready, you call
> windowInvalidateRectangle on the DrawWindow of the DrawingArea. This
> will trigger the expose handler.
>
> In the expose handler of the DrawingArea, you retrieve the Pixmap from
> the worker thread and you copy it to the screen using
> Drawable.drawDrawable. You should probably turn off double buffering
> using widgetSetDoubleBuffered since this just means the pixmap is copied
> twice.
>
> In order to avoid that you show half-ready images, your worker thread
> could keep two Pixmaps: one for drawing, the other one containing the
> last complete image.

Thanks - this actually fits quite nicely with the way we do things in 
ThreadScope already.  We keep track of a separate Surface already so 
that we can implement fast scrolling by copying it directly to the 
widget in the expose event, and so that we don't have to re-render the 
whole window when the cursor moves (the cursor is a line overlaid on top 
of the rendered graph).

What I plan to do is have a thread in the background doing a high-detail 
render, and swap the rendered surface in when it is complete.  Every 
time an expose event is received, we do a quick low-detail render, and 
instruct the background thread to start work on a high-detail render in 
the background.  It should make motion quite snappy.

Cheers,
        Simon



> I've never tried this, but this is how I understand the documentation.
>
> Cheers,
> Axel.
>
>> Cheers,
>>      Simon
>>
>> On 22/11/09 19:58, Axel Simon wrote:
>>> Dear Simon, Duncan,
>>>
>>> -threaded now works with Gtk2Hs. See below.
>>>
>>>
>>> On Tue, 2009-11-10 at 14:14 +0000, Simon Marlow wrote:
>>>> On 10/11/2009 13:52, Axel Simon wrote:
>>>
>>>>>> Does the traceback in my original message give you enough information?
>>>>>> (reproduced at the end of this message)
>>>>>
>>>>> Well, you omitted 'various' stuff. I agree that something is calling
>>>>> back into C when it shouldn't. Are there any function names between
>>>>> frame 6 and 44 that would give me a clue where we've been negligent?
>>>>
>>>> Ah yes, sorry.  Here's the full trace:
>>>>
>>>> (gdb) where
>>>> #0  0x0000003c0aa0af19 in pthread_cond_wait@@GLIBC_2.3.2 () from
>>>> /lib64/libpthread.so.0
>>>> #1  0x00000000005ac6e9 in waitCondition ()
>>>> #2  0x00000000005c67ab in waitForReturnCapability ()
>>>> #3  0x00000000005a3f17 in rts_lock ()
>>>> #4  0x00000000004ce397 in SystemziGlibziGObject_d1wV ()
>>>> #5  0x0000003c10cd8eed in ?? () from /usr/lib64/libgtk-x11-2.0.so.0
>>>> #6  0x0000003c0ba0d6a8 in g_object_unref () from /lib64/libgobject-2.0.so.0
>>>> #7  0x0000003c10ccebc7 in gtk_tree_view_remove_column () from
>>>
>>> I understand now where this error is. There is a call in your program to
>>> cellLayoutSetAttributes. This function installs certain callbacks that
>>> Gtk+ tries to free in the stack trace above. The call stack above is
>>> triggered by
>>>
>>>> #41 0x0000003c0ba0d632 in g_object_unref ()
>>> from /lib64/libgobject-2.0.so.0
>>>> #42 0x00000000005abdfd in runAllCFinalizers ()
>>>
>>> ... and I suppose runAllCFinalizers is the GC and an 'unsafe' call from
>>> Haskell. Thus, it is actually only possible  to use the C function
>>> freeHaskellPtr. I do that now.
>>>
>>>
>>>>      (3) use Haskell finalizers with idleAdd as a temporary workaround.
>>>>
>>>> (3) is by far the easiest solution, but it may have unacceptable
>>>> performance, I'd interested to know if that's the case.  The runtime
>>>> does batch multiple finalizers so they don't each get a separate Haskell
>>>> thread, so it might not be too bad.
>>>>
>>>> I'm not completely averse to doing (1) if it's absolutely necessary, but
>>>> I'd like to do something that avoids having a dependency on a future
>>>> version of GHC.  And all things being equal, we should avoid adding new
>>>> features to GHC because they're hard to remove again.
>>>
>>> So now there are two kinds of finalizers:
>>>
>>> (1) those that directly free the C GObject which are used in Cairo and
>>> (in the future) Pango, Pixbuf, and all other libraries whose objects do
>>> not call back into Haskell.
>>>
>>> (2) all finalizers of Gtk+ and libraries that build upon Gtk+
>>> (sourceview, etc). These call a special finalizer that enqueues the
>>> object to be finalized into an array and install a an g_idle_add handler
>>> that will run the finalizers from the main iteration loop of Gtk+ and,
>>> thus, from the right thread and from a safe call.
>>>
>>> All objects in (2) can therefore call back to Haskell while they are
>>> being destroyed. I have therefore moved the possibility to add a WeakRef
>>> (a function that is called when a GObject is finalized) to from GObject
>>> to Graphics.UI.Gtk.Abstract.Object which means they can only be
>>> installed on objects that fall into category (2).
>>>
>>> So the darcs version of Gtk2Hs with -threaded should now work as
>>> expected. You're still responsible to call Gtk2Hs function from the same
>>> Haskell thread. But you can create Cairo drawings and Pagno stuff in
>>> different threads and pass them to the main thread.
>>>
>>> Cheers,
>>> Axel.
>>>
>>>
>


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Gtk2hs-devel mailing list
Gtk2hs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gtk2hs-devel

Reply via email to