caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] OpenGL and LWT
@ 2014-03-15 17:37 Richard Neswold
  2014-03-17 10:09 ` Jeremie Dimino
  0 siblings, 1 reply; 11+ messages in thread
From: Richard Neswold @ 2014-03-15 17:37 UTC (permalink / raw)
  To: caml-list

Hello,

What would be the appropriate way to use LWT and LabGL together?

My gut feeling would be to have the core model and logic to be LWT with a 'detached' thread executing the OpenGL main loop. The thread would get events through the reactive module and would update the display accordingly.

The problem is I'm still trying to wrap my head around LWT and I'm not sure a detached thread can participate with the LWT environment it was spawned from. It appears the detached thread is supposed to do something and eventually return a value.

Is the correct approach to use a detached thread to make the individual OpenGL calls?

Any recommendations or resources on the subject would be appreciated.

--
Rich

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] OpenGL and LWT
  2014-03-15 17:37 [Caml-list] OpenGL and LWT Richard Neswold
@ 2014-03-17 10:09 ` Jeremie Dimino
  2014-03-17 10:32   ` Ivan Gotovchits
  2014-03-17 10:34   ` Török Edwin
  0 siblings, 2 replies; 11+ messages in thread
From: Jeremie Dimino @ 2014-03-17 10:09 UTC (permalink / raw)
  To: Richard Neswold; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 1263 bytes --]

Hi,

On Sat, Mar 15, 2014 at 5:37 PM, Richard Neswold <rich.neswold@gmail.com>wrote:

> Hello,
>
> What would be the appropriate way to use LWT and LabGL together?
>
> My gut feeling would be to have the core model and logic to be LWT with a
> 'detached' thread executing the OpenGL main loop. The thread would get
> events through the reactive module and would update the display accordingly.
>
> The problem is I'm still trying to wrap my head around LWT and I'm not
> sure a detached thread can participate with the LWT environment it was
> spawned from. It appears the detached thread is supposed to do something
> and eventually return a value.
>

Yes, the purpose of Lwt_preemptive.detach is to execute a blocking action
in a separate system thread in order not to block all lwt threads. And from
another system thread you cannot run lwt code directly, you have to use
Lwt_preemptive.run_in_main.


> Is the correct approach to use a detached thread to make the individual
> OpenGL calls?
>

I think that would be very slow, as in involves system thread
synchronization.


> Any recommendations or resources on the subject would be appreciated.
>

You could try to assume  that OpenGL calls are fast and perform them in the
same thread as lwt.

-- 
Jeremie

[-- Attachment #2: Type: text/html, Size: 1978 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] OpenGL and LWT
  2014-03-17 10:09 ` Jeremie Dimino
@ 2014-03-17 10:32   ` Ivan Gotovchits
  2014-03-17 13:39     ` Rich Neswold
  2014-03-17 10:34   ` Török Edwin
  1 sibling, 1 reply; 11+ messages in thread
From: Ivan Gotovchits @ 2014-03-17 10:32 UTC (permalink / raw)
  To: Richard Neswold; +Cc: Jeremie Dimino, caml-list


>
> Hello,
> 
> What would be the appropriate way to use LWT and LabGL together?

Unfortunately, I don't know how LabGL is organized. If it has an event
loop it will be better to incorporate it into main event loop of lwt, as
it was done for lablgtk. Otherwise, I see several solutions. First, use
Lwt_unix jobs, or, if you find it to tedious, just use an async task
(see Lwt.async). There is no particular reason to use detached threads
because they will be serialized by the big lock. 


> You could try to assume  that OpenGL calls are fast and perform them
> in the same thread as lwt.

But if the assumption is wrong you're in a big trouble. 



-- 
         (__) 
         (oo) 
   /------\/ 
  / |    ||   
 *  /\---/\ 
    ~~   ~~   
...."Have you mooed today?"...

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] OpenGL and LWT
  2014-03-17 10:09 ` Jeremie Dimino
  2014-03-17 10:32   ` Ivan Gotovchits
@ 2014-03-17 10:34   ` Török Edwin
  2014-03-17 11:01     ` Daniel Bünzli
  1 sibling, 1 reply; 11+ messages in thread
From: Török Edwin @ 2014-03-17 10:34 UTC (permalink / raw)
  To: caml-list

On 03/17/2014 12:09 PM, Jeremie Dimino wrote:
> Hi,
> 
> On Sat, Mar 15, 2014 at 5:37 PM, Richard Neswold <rich.neswold@gmail.com <mailto:rich.neswold@gmail.com>> wrote:
> 
>     Hello,
> 
>     What would be the appropriate way to use LWT and LabGL together?
> 
>     My gut feeling would be to have the core model and logic to be LWT with a 'detached' thread executing the OpenGL main loop. The thread would get events through the reactive module and would update the display accordingly.
> 
>     The problem is I'm still trying to wrap my head around LWT and I'm not sure a detached thread can participate with the LWT environment it was spawned from. It appears the detached thread is supposed to do something and eventually return a value.
> 
> 
> Yes, the purpose of Lwt_preemptive.detach is to execute a blocking action in a separate system thread in order not to block all lwt threads. And from another system thread you cannot run lwt code directly, you have to use Lwt_preemptive.run_in_main.

Be careful to have an OpenGL context set as current on the thread(s) from which you make GL calls. See:
https://www.opengl.org/wiki/OpenGL_and_multithreading
http://www.equalizergraphics.com/documentation/parallelOpenGLFAQ.html

I don't think you'll get a performance improvement from launching multiple GL calls in different (Lwt) threads.

>  
> 
>     Is the correct approach to use a detached thread to make the individual OpenGL calls?
> 
> 
> I think that would be very slow, as in involves system thread synchronization. 
>  
> 
>     Any recommendations or resources on the subject would be appreciated.
> 
> 
> You could try to assume  that OpenGL calls are fast and perform them in the same thread as lwt.

Well there are a few that are slow, like swapping buffers which can wait for vsync.

I think its best to make GL calls from just *one* thread, either your application's main thread, or a dedicated rendering thread.
You can probably build a Lwt.t that waits for the rendering thread to finish one frame using
Lwt_unix.make_notification/send_notification for thread-safe Lwt notification, coupled with Lwt.wait/Lwt.wakeup_result.

Best regards,
--Edwin


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] OpenGL and LWT
  2014-03-17 10:34   ` Török Edwin
@ 2014-03-17 11:01     ` Daniel Bünzli
  0 siblings, 0 replies; 11+ messages in thread
From: Daniel Bünzli @ 2014-03-17 11:01 UTC (permalink / raw)
  To: caml-list

Le lundi, 17 mars 2014 à 11:34, Török Edwin a écrit :
> Well there are a few that are slow, like swapping buffers which can wait for vsync.

Yes and you should make sure that the C bindings to these calls release the ocaml runtime system lock during the call. Other slow calls are memory transfer calls (e.g. glBufferData). This book chapter [1] may be worth reading.

Daniel

[1] http://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-AsynchronousBufferTransfers.pdf



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] OpenGL and LWT
  2014-03-17 10:32   ` Ivan Gotovchits
@ 2014-03-17 13:39     ` Rich Neswold
  2014-03-17 14:05       ` Daniel Bünzli
  0 siblings, 1 reply; 11+ messages in thread
From: Rich Neswold @ 2014-03-17 13:39 UTC (permalink / raw)
  Cc: caml-list

On Mon, Mar 17, 2014 at 5:32 AM, Ivan Gotovchits <ivg@ieee.org> wrote:
> Unfortunately, I don't know how LabGL is organized.

Most OpenGL bindings (including LabGL) include 'libglut', which is a
library that is bundled with OpenGL that opens a UI window with an
OpenGL context in it. It would be nice to use this library because it
hides these details (i.e. the same code runs on Unix and MacOSX and
Windows.) Unfortunately, the way libglut works is you call main_loop()
which never returns. Before calling main_loop(), you register
callbacks for mouse and keyboard events. You can also register a
callback for periodic timeouts. Lastly, there's a callback which gets
called whenever the libglut main loop is "idle" (with unspecified
latencies, frequency, or guarantees.)

> If it has an event loop it will be better to incorporate it into main event loop of lwt, as
> it was done for lablgtk. Otherwise, I see several solutions. First, use
> Lwt_unix jobs, or, if you find it to tedious, just use an async task
> (see Lwt.async).

What I'll try is to run the GLUT main loop in a async task and when
the idle callback is called, I'll call lwt.yield. The keyboard and
mouse callbacks can post lwt.react.events. This set-up might work.

Thanks!

-- 
Rich

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] OpenGL and LWT
  2014-03-17 13:39     ` Rich Neswold
@ 2014-03-17 14:05       ` Daniel Bünzli
  2014-03-17 14:13         ` Daniel Bünzli
  2014-03-17 22:50         ` Richard Neswold
  0 siblings, 2 replies; 11+ messages in thread
From: Daniel Bünzli @ 2014-03-17 14:05 UTC (permalink / raw)
  To: Rich Neswold; +Cc: caml-list

Le lundi, 17 mars 2014 à 14:39, Rich Neswold a écrit :
> On Mon, Mar 17, 2014 at 5:32 AM, Ivan Gotovchits <ivg@ieee.org (mailto:ivg@ieee.org)> wrote:
> > Unfortunately, I don't know how LabGL is organized.
>  
> Most OpenGL bindings (including LabGL) include 'libglut', which is a
> library that is bundled with OpenGL that opens a UI window with an
> OpenGL context in it. It would be nice to use this library because it
> hides these details (i.e. the same code runs on Unix and MacOSX and
> Windows.) Unfortunately, the way libglut works is you call main_loop()
> which never returns. Before calling main_loop(), you register
> callbacks for mouse and keyboard events. You can also register a
> callback for periodic timeouts. Lastly, there's a callback which gets
> called whenever the libglut main loop is "idle" (with unspecified
> latencies, frequency, or guarantees.)

I wouldn't use glut which is no longer bundled on osx, is quite limited in functionality and reclaims your main loop. Use SDL, it provides similar functionality to setup an OpenGL context in a platform independent way but it doesn't reclaim control on your main() which will make integration with lwt trivial. There is:  

http://ocamlsdl.sourceforge.net/home.html

I also wrote newer and lower level bindings that target SDL2, they are not released yet but are becoming stable see:

https://sympa.inria.fr/sympa/arc/caml-list/2013-12/msg00105.html

(the heisenbug on osx mentioned in that message can be solved see [1]).  

Best,

Daniel

[1] http://lists.ocaml.org/pipermail/ctypes/2014-February/000066.html




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] OpenGL and LWT
  2014-03-17 14:05       ` Daniel Bünzli
@ 2014-03-17 14:13         ` Daniel Bünzli
  2014-03-17 22:50         ` Richard Neswold
  1 sibling, 0 replies; 11+ messages in thread
From: Daniel Bünzli @ 2014-03-17 14:13 UTC (permalink / raw)
  To: Rich Neswold; +Cc: caml-list



Le lundi, 17 mars 2014 à 15:05, Daniel Bünzli a écrit :

> I wouldn't use glut which is no longer bundled on osx,

Well that's wrong. But it's no longer recommended, see https://developer.apple.com/library/mac/qa/qa1613/_index.html

Daniel



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] OpenGL and LWT
  2014-03-17 14:05       ` Daniel Bünzli
  2014-03-17 14:13         ` Daniel Bünzli
@ 2014-03-17 22:50         ` Richard Neswold
  2014-03-17 23:50           ` Daniel Bünzli
  1 sibling, 1 reply; 11+ messages in thread
From: Richard Neswold @ 2014-03-17 22:50 UTC (permalink / raw)
  To: Daniel Bünzli; +Cc: caml-list

> On Mar 17, 2014, at 9:05 AM, Daniel Bünzli <daniel.buenzli@erratique.ch> wrote:
> I wouldn't use glut which is no longer bundled on osx, is quite limited in functionality and reclaims your main loop. Use SDL, it provides similar functionality to setup an OpenGL context in a platform independent way but it doesn't reclaim control on your main() which will make integration with lwt trivial.

The SDL libraries look much better to use. Thanks for the suggestion!

Sorry, though. I'm still not fully understanding how to interface the two. I see that, in SDL, I can call Tsdl.Sdl.wait_event to block and wait for events to get posted. But in what context should I call this function? In my LWT environment, this would block the entire application. Lwt.Async threads would also do that. I could use 'detach' to use an OS thread, but then I'm back to the same problem as libglut: a secondary thread needs to communicate with the main LWT environment which itself can't make SDL calls since the secondary thread "owns" the SDL context.

I could have an Lwt thread call Sdl.poll_event and then go to sleep if no events were available, but I'm trying to make this driven by events and not resort to polling, if possible.

I must be missing some detail in getting these libraries to work together trivially. Sorry for my misunderstanding.

--
Rich

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] OpenGL and LWT
  2014-03-17 22:50         ` Richard Neswold
@ 2014-03-17 23:50           ` Daniel Bünzli
  2014-03-19 12:01             ` Rich Neswold
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel Bünzli @ 2014-03-17 23:50 UTC (permalink / raw)
  To: Richard Neswold; +Cc: caml-list

Le lundi, 17 mars 2014 à 23:50, Richard Neswold a écrit :
> I could have an Lwt thread call Sdl.poll_event and then go to sleep if no events were available, but I'm trying to make this driven by events and not resort to polling, if possible.

There is certainly more than one way to do that, but that's what I do at the moment (with another cooperative threading library). Favor the treatement of the UI events, if there's no UI event run the scheduler for 10ms.  

let rec loop deadline =  
  while Sdl.poll_event e do do_event e done;
  run_scheduler ~timeout:10;  
  loop ()

Regarding Tsdl.Sdl.wait_event, it's not really better than that, if you have a look at its C implementation [1] you'll see it tries to get an event and if none is available it will sleep for 10ms before trying again. This means that any SDL based program using Sdl.wait_event, constantly uses ~1.5% cpu (at least on osx), you should be able to bring that down by writing your own loop as above and augmenting the timeout value when your application is not in the foreground.  

Best,

Daniel

[1] http://hg.libsdl.org/SDL/file/4c01875a4620/src/events/SDL_events.c#l421



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Caml-list] OpenGL and LWT
  2014-03-17 23:50           ` Daniel Bünzli
@ 2014-03-19 12:01             ` Rich Neswold
  0 siblings, 0 replies; 11+ messages in thread
From: Rich Neswold @ 2014-03-19 12:01 UTC (permalink / raw)
  To: Daniel Bünzli; +Cc: OCaml List

On Mon, Mar 17, 2014 at 6:50 PM, Daniel Bünzli
<daniel.buenzli@erratique.ch> wrote:
> There is certainly more than one way to do that, but that's what I do at the moment (with another cooperative threading library). Favor the treatement of the UI events, if there's no UI event run the scheduler for 10ms.
>
> let rec loop deadline =
>   while Sdl.poll_event e do do_event e done;
>   run_scheduler ~timeout:10;
>   loop ()
>
> Regarding Tsdl.Sdl.wait_event, it's not really better than that, if you have a look at its C implementation [1] you'll see it tries to get an event and if none is available it will sleep for 10ms before trying again. This means that any SDL based program using Sdl.wait_event, constantly uses ~1.5% cpu (at least on osx), you should be able to bring that down by writing your own loop as above and augmenting the timeout value when your application is not in the foreground.

Thank you for all your help! I'll approach the problem using SDL.

-- 
Rich

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-03-19 12:01 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-15 17:37 [Caml-list] OpenGL and LWT Richard Neswold
2014-03-17 10:09 ` Jeremie Dimino
2014-03-17 10:32   ` Ivan Gotovchits
2014-03-17 13:39     ` Rich Neswold
2014-03-17 14:05       ` Daniel Bünzli
2014-03-17 14:13         ` Daniel Bünzli
2014-03-17 22:50         ` Richard Neswold
2014-03-17 23:50           ` Daniel Bünzli
2014-03-19 12:01             ` Rich Neswold
2014-03-17 10:34   ` Török Edwin
2014-03-17 11:01     ` Daniel Bünzli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).