Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: synchronizing opengl with multiple threads

  1. #1
    Junior Member Newbie
    Join Date
    May 2011
    Posts
    16

    synchronizing opengl with multiple threads

    I work on an application that is using one GL context per window that are each on their own thread. There are 4 windows and a fifth shared context.

    The application uses glFenceSync object's to try and ensure everything stay's nicely synchroized.

    However I was just reading OpenGL Insights chapter 34 Timer Queries and it is makes it look like there's not much of a point in separating context's into different threads being that in figure 34.1 it has the different context's running in parallel. The work was submitted from 1 thread.

    If I were able to find a picture of the figure I'm referring too I would have posted it, sorry.

    My question is: What is the best way to handle drawing to multiple windows?
    Are there any papers / books on this topic? How was this kind of thing handled in the past, before sync objects?

    Some more background, is that even though there are 4 windows being drawn too, only 1 (sometimes 2) have any "real" work load. The other windows have pretty minimal things being drawn to them.

    Would a better (faster) solution be to have a render target for each window and draw everything to those from one context then let each window draw only their render target?

    If there is anything that is not clear, please point it out.

    Thanks

  2. #2
    Member Regular Contributor
    Join Date
    Jan 2005
    Location
    USA
    Posts
    411
    I do not want to hijack the "thread". But I am curious about the modern state of OpenGL in terms of calling the APIs from any given thread with respect to a particular context that might reside on its own thread.

    With Direct3D (9) it doesn't matter which thread called the API. I think this is easier for integration. Though I still do not know if a Present will take control of the device interface's critical section or not. That would be a game changer. I assume a Present is handled independently since it must wait for the vertical blank. I will have to do my own tests at some point since the Microsoft forums are a no man's land.

    I would like to adopt the same approach with OpenGL (3.2 I think) without having to implement a queue that mirrors the relevant OpenGL APIs if possible.

    Ontopic: If a context is bound to a thread, and presenting to the window is a blocking operation on that thread, then I would think going with one render target per window would not work out if you need to do more than one presentation per vertical blank period. But I have only worked with WebGL (in terms of OpenGL) for the last several years, so I am pretty far behind and very rusty for that matter.

    EDITED: If the presentation is arranged to happen immediately (not synchronized) then multiple render targets would surely definitely work. Not sure if "synchronizing" in the subject means that the windows represent traditional frame buffers or not.
    Last edited by michagl; 09-08-2012 at 08:28 AM. Reason: On second thought^
    God have mercy on the soul that wanted hard decimal points and pure ctor conversion in GLSL.

  3. #3
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    I do not want to hijack the "thread".
    Then why didn't you just make your own thread? It's not like threads are a scarce resource or something...

    Though I still do not know if a Present will take control of the device interface's critical section or not.
    What is a "Present"?

  4. #4
    Member Regular Contributor
    Join Date
    Jan 2005
    Location
    USA
    Posts
    411
    Quote Originally Posted by Alfonse Reinheart View Post
    Then why didn't you just make your own thread? It's not like threads are a scarce resource or something...



    What is a "Present"?
    Because I am also interested in threads with respect to OpenGL which amounts to the same issue.

    Present would be the equivalent to SwapBuffers I guess in Windows. Not sure about X. With Direct3D (9; why use anything else) you can target an arbitrary region in any window with any sub region of the back buffer. With copy (double buffer) semantics and immediate refresh interval it basically feels like a blit, if that is not what it is. With "discard" you must transfer the back buffer corner to corner over the entire window (from what I can see that looks like all OpenGL is able to do; but I probably need updated documentation)
    Last edited by michagl; 09-08-2012 at 01:25 PM.
    God have mercy on the soul that wanted hard decimal points and pure ctor conversion in GLSL.

  5. #5
    Senior Member OpenGL Pro Aleksandar's Avatar
    Join Date
    Jul 2009
    Posts
    1,161
    Quote Originally Posted by tamato View Post
    However I was just reading OpenGL Insights chapter 34 Timer Queries and it is makes it look like there's not much of a point in separating context's into different threads being that in figure 34.1 it has the different context's running in parallel. The work was submitted from 1 thread.
    Fig.34.1 in OpenGL Insights has nothing with multi-context execution. That figure just illustrates pipelined and asynchronous execution of multiple draw calls.

    Using a single GL context removes need for the synchronization, since GL guaranties in order execution (except data transfers, and maybe something else, but it is properly handled and optimized by the drivers). Using multiple contexts is required when pixel formats of the windows differ. If the pixel format is the same for all windows a single context can be used. Sometimes multiple contexts are used for asynchronous update. A benefit from such update is questionable and heavily depends on the certain implementation. Be aware that OpenGL serializes calls targeting a single context, but cannot over multiple contexts. In the case of multiple contexts additional synchronization is necessary (like you do, with both critical sections for the CPU and sync objects for the GPU). Also, multiple contexts do not execute in parallel. They do it concurrently.

  6. #6
    Member Regular Contributor
    Join Date
    Jan 2005
    Location
    USA
    Posts
    411
    Does anyone know of a good resource pertaining to multi threaded OpenGL. I am totally ignorant. I see the wiki here. I will see if I can find anything later.

    http://www.opengl.org/wiki/Context

    So can a thread take control of a context? Or is it better to share resources? Can the final write to the display be done without being the current context?

    I would just like to know. But I reckon these questions are pertinent to the discussion. I'm sorry. I've been working with Direct3D for way too long due to project constraints.
    God have mercy on the soul that wanted hard decimal points and pure ctor conversion in GLSL.

  7. #7
    Senior Member OpenGL Pro Aleksandar's Avatar
    Join Date
    Jul 2009
    Posts
    1,161
    Quote Originally Posted by michagl View Post
    Does anyone know of a good resource pertaining to multi threaded OpenGL.
    An interesting artical about the topic can be find in chapter 10 - "Exploiting Parallelism in Resource Preparation" from the "3D Engine Design for Virtual Globes" by Patrick Cozzi and Kevin Ring.

    Quote Originally Posted by michagl
    So can a thread take control of a context? Or is it better to share resources?
    A thread has to "take control" and make GL context current in order to issue any of the commands. If you have several contexts, making a share-group is the only way to prevent data multiplication if they use the same resources. Otherwise, you have no particular reason to make uploading data through another context. Of course, data creation and/or download to main memory should be done in a separeta thread. Personally, I like to leave upload data to GPU memory to a drawing thread, but have quotas for update in a single frame to make frame-rate consistent.

    Quote Originally Posted by michagl
    Can the final write to the display be done without being the current context?
    Of course! SwapBuffers (on MS Windows) is not an OpenGL command. Under the hood, it flushes all drawing commands from all threads drawing to the same window.

  8. #8
    Member Regular Contributor
    Join Date
    Jan 2005
    Location
    USA
    Posts
    411
    ^Thanks (but no thanks on recommending offline resources

    What I meant by taking control (I apologize) was not a thread making its context the current context, but rather a thread taking control of a context that originated on another thread or is passed around amongst multiple threads (to use the linear raster facilities as necessary)

    PS: I am assuming this information is all supplemental to the OP as it is very open ended (I would personally be bewildered if someone created a post with an identical line of questioning to my own post; so I won't do that, even though it has been suggested that I should)
    God have mercy on the soul that wanted hard decimal points and pure ctor conversion in GLSL.

  9. #9
    Member Regular Contributor
    Join Date
    Jan 2005
    Location
    USA
    Posts
    411
    EDITED: Oh I see now.

    Quote Originally Posted by wglMakeCurrent
    A rendering context can be current to only one thread at a time. You cannot make a rendering context current to multiple threads.
    I was under the impression (read: I had imagined) that the contexts belonged to a physical device of which there can be only one current context. Sorry.

    The docs I am looking at do not say what happens if a thread makes an in use context current. Does wglMakeCurrent block until it is not current? Or does it return 0 (failure) and whatever the case how costly is it allowed to be if you were to regularly trade a context between threads?

    If I have not already said so. I am basically wondering if I will have to implement a marshaled queue for all of the pertinent API calls in order to allow threads flexible access to a shared context (without forking the context ideally) or if I can just swap the context between threads without much penalty.

    Also I am wondering. Is the pixel format of the HDC really the only requirement? What happens if the HDC is on the display of another physical device (with the same pixel format) ? I don't see anything selecting a device in my docs anyway. But my docs are very old. I apologize. I favor them because they are offline.

    One thing OpenGL has is SwapBuffers. It's not obvious that the Present method of the D3D (9) device will not block all access to the device, because it is a method of the device interface, and the docs only mention that there is a global per device (interface surely) critical section. I asked the question in Microsoft's forums and got no answers. But every MS forum is an absolute ghost town anyway. Even compared to this place

    On the other hand it would seem completely bone headed for the D3D Present operation to block the rest of the methods (while it waits for the vertical blank period)
    God have mercy on the soul that wanted hard decimal points and pure ctor conversion in GLSL.

  10. #10
    Senior Member OpenGL Pro Aleksandar's Avatar
    Join Date
    Jul 2009
    Posts
    1,161
    Quote Originally Posted by michagl View Post
    The docs I am looking at do not say what happens if a thread makes an in use context current. Does wglMakeCurrent block until it is not current? Or does it return 0 (failure) and whatever the case how costly is it allowed to be if you were to regularly trade a context between threads?
    wglMakeCurrent fails if the context is in use. You may need to wait and check whether it succeeds. But... Why would you do that?
    I have to admit that I did it long time ago, but now it seems to me that it is a better practice to use GL context only from a single thread. That thread owns context and issues commands exclusively. All other threads just post messages to a drawing thread.

    Quote Originally Posted by michagl View Post
    If I have not already said so. I am basically wondering if I will have to implement a marshaled queue for all of the pertinent API calls in order to allow threads flexible access to a shared context (without forking the context ideally) or if I can just swap the context between threads without much penalty.
    Refer to a previous suggestion.

    Quote Originally Posted by michagl View Post
    Also I am wondering. Is the pixel format of the HDC really the only requirement? What happens if the HDC is on the display of another physical device (with the same pixel format) ? I don't see anything selecting a device in my docs anyway.
    You can use GL context with all windows having the same pixel format without any problem. Pixel format dictates how framebuffer have to be created. Anyway you can check whether it works or not. I’m just encouraging you to try. It worked for me.

    Quote Originally Posted by michagl View Post
    But every MS forum is an absolute ghost town anyway. Even compared to this place
    I wouldn’t agree with you that opengl.org is a ghost town. This is the most lively discussion forum about OpenGL in the universe.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •