Grey Screen of Death

Home Forums Syphon Syphon Development – Developer Grey Screen of Death

Viewing 18 posts - 1 through 18 (of 18 total)
  • Author
    Posts
  • #17607
    MusicMan3001
    Participant

    I’ve been developing with Syphon and something I’ve never seen before (on a Mac) keeps happening — my entire system reboots.  It happens when I have the Simple Server running, and a client (which I developed) running in my own app, and then I drag the Simple Server window to resize it.  Bam.  Computer restarts.  Has anyone else seen this?

    While looking into this, I noticed that there doesn’t seem to be a way to lock the server’s context from the client.  Which means that, couldn’t the SyphonImage that I request with newFrameImageForContext become invalid immediately after I request it?  I.e., if the Server is resized?  So now, my SyphonImage could be referring to a texture that’s no longer relevant.

    It seems like there should be a way to tell the server that the texture is being used in the client right now, and that the server shouldn’t destroy it, even if it’s resizing.

    Making sense at all?  Any help appreciated.

    #17628
    bangnoise
    Keymaster

    Syphon takes care of synchronisation (well, the underlying IOSurface does). As long as you retain a SyponImage in the client app, the surface remains valid even if the server is no longer using it.

    Can you recreate the problem using only Simple Server and Simple Client? If not, can you provide an Xcode project for a minimal client app which does recreate the problem?

    Also what hardware and OS version are you on?

    #17629
    MusicMan3001
    Participant

    No, I can’t recreate it with only the Simple Server and Simple Client.  So it’s definitely something I’m doing in my app.  Unfortunately my app is too big to share here, and I’m not sure I could whittle it down easily.

    I have a MacBook Pro 9,2 with 10.8.2.  After the computer restarts, and I view the error report, it definitely seems to be an issue with the graphics driver.  Strange.  I’m really not understanding why the entire system would reboot instead of just crashing the app.  It makes it really difficult to debug!

    I’ll have to do some more investigating and get back to you I guess.  Thanks.

    #17630
    bangnoise
    Keymaster

    Welcome to the world of GPU-driver induced kernel panics… They shouldn’t happen, but they are easily triggered by abusing the GL.

    Creating a reduction is my usual strategy when faced with kernel panics – often it’s the quickest way to identify the bad code, even though it can be a pain. Also, if you haven’t already, run your app in OpenGL Profiler, breaking on errors, and see if it throws any GL errors prior to causing the KP.

    #17637
    MusicMan3001
    Participant

    Commenting out this line in my code prevents the problem:

    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, myTexName);

    Strange, right?  Any ideas?

    Also, is there some reason why you don’t just support GL_TEXTURE_2D?

     

    #17638
    bangnoise
    Keymaster

    Impossible to know without knowing what myTexName refers to and what you have done and are doing with it.

    We do support GL_TEXTURE_2D for serving. The underlying IOSurface only supports GL_TEXTURE_RECTANGLE. Is it a problem to you?

    #17639
    MusicMan3001
    Participant

    Sorry, I should have given more detail.  Basically I am doing this:

    SyphonImage *myFrame = [myClient newFrameImageForContext:myContext];
    if (myFrame)
    {
    GLuint myTexName = [myFrame textureName];
    NSSize myTexSize = [myFrame textureSize];

    … etc.  My code is virtually identical to that of the Simple Client.

    Keep in mind that this works perfectly fine most of the time.  It’s only when the Simple Server is resized that the problem occurs.

    I was just thinking that maybe GL_TEXTURE_2D would be less problematic, but maybe not.

    #17655
    bangnoise
    Keymaster

    Sounds like a problem with your code. If you can share a reduction which reproduces the issue we can take a look at that.

    #17656
    vade
    Keymaster

    Try to use GL Profiler and break on error, and introspect your GL State, or see if you can reproduce on another GPU, you might be hitting an edge case.

    #29285
    MusicMan3001
    Participant

    In viewing your issue list in response to my other post, it seems that the following issue may be relevant to the problem I have described above:
    https://github.com/Syphon/Syphon-Framework/issues/2

    #29286
    bangnoise
    Keymaster

    Try cloning, building and linking against the mt-issue branch from GitHub and see if that solves it (and let us know).

    #58967
    MusicMan3001
    Participant

    After a long time without solving this issue (and thus having occasional crashes), I think I finally have some insight. Can you give me your opinion? Hopefully it will help someone else if it’s the right answer.

    I’m running Syphon in a plugin, which doesn’t have much access to the host app’s state. So, I never thought twice about using the static function [NSOpenGLContext currentContext]. But now I realize there’s a chance that this function might not return the right context. And if it’s the wrong one, and Syphon tries to use it, things go south pretty quickly.

    Am I thinking about it correctly? The proper solution would require I have direct access to the variable which represents the actual context for the window, right?

    #58968
    MusicMan3001
    Participant

    Ok, actually I don’t think that’s the problem. But I think this is:
    http://www.cocoabuilder.com/archive/cocoa/107699-nsopenglview-from-second-nsthread.html

    Apparently all GL functions need to be locked when rendering isn’t in the main thread. NSOpenGLView will call GL functions from the main thread when the window is resized, etc. So not only does the secondary thread have to be locked, but all functions in NSOpenGLView have to be overriden and locked as well.

    #58969
    vade
    Keymaster

    Thats not quite correct –

    OpenGL access has to be *serialized* – meaning you cannot make concurrent requests to OpenGL from multiple threads, as you will corrupt the command stream submitted to the GPU, and cause issues.

    OpenGL is a state machine, you twiddle state on and off and submit objects, and then render at the current configuration. Changes you make persist, and order of operations matter.

    So in terms of multithreading OpenGL, you have to serialize access to a OpenGL Context.

    Something like

    Thread A:
    Lock for OpenGL
    Draw / Resize Viewport
    Render/ Flush the screen
    Unlock for OpenGL

    Thread B:
    Do something to prepare expensive calculations for OpenGL
    Lock for OpenGL
    Submit OpenGL Commands
    Unlock OpenGL
    Continue on your way

    Hope that helps.

    #58970
    vade
    Keymaster

    To be clear, you can use OpenGL on a secondary thread without locks, if you never touch it from another thread (i.e., its guaranteed to be serial on that thread and that thread only).

    #58971
    MusicMan3001
    Participant

    I understand what you are saying. But I found this link (apologies that it’s a book and was written in 2007): https://books.google.com/books?id=Ryb-k7jrPnIC&pg=PT74&lpg=PT74&dq=what+commands+does+nsopenglview+issue&source=bl&ots=ql64KJbQ2q&sig=fugHPEgKub7RoiT668Fq_w1AIvM&hl=en&sa=X&ei=3MIyVYWPLZbhoASd_YHgBQ&ved=0CDIQ6AEwAw#v=onepage&q=what%20commands%20does%20nsopenglview%20issue&f=false

    According to that, and assuming it’s still relevant, the NSOpenGLView class makes implicit OpenGL calls when the window is resized. Thus, from a programming perspective, you can’t control when GL commands will be issued on the main thread. Hence, when using a second thread to do rendering, locking the context is required to ensure the main thread doesn’t interrupt the command stream. And vice versa.

    See what I’m saying?

    #58972
    bangnoise
    Keymaster

    Aren’t you both saying the same thing?

    In a plugin the situation is complicated by the actions of the host app. Usually the plugin interface will define the behaviour in its documentation, and you needn’t worry about locking at all as long as you adhere to its policies. If it doesn’t, then it’s possible the host may be using some locking mechanism outside your control, and then you have a real problem. If it suits your purposes then you can create a new shared GL context and use that with your own protection to ensure serial access.

    If this is the same problem as you were having in January, then it would definitely be worth producing a reduction which exhibits the behaviour which you can share with us. Also knowing a little more about the host app and its plugin interface might help us to help you.

    #58978
    MusicMan3001
    Participant

    All I was saying is that you actually can’t use OpenGL on a secondary thread without locks.

    Direct quote from Apple’s documentation: “When you use an NSOpenGLView object with OpenGL calls that are issued from a thread other than the main one, you must set up mutex locking. ”

    I’ve gone ahead and implemented these locks in the code I’m working on, so I’ll report back in a bit if I’m still getting crashes.

Viewing 18 posts - 1 through 18 (of 18 total)
  • You must be logged in to reply to this topic.