2

Following up on the answer to How to use GLUT with libdispatch?, I'm now using GLFW instead —

The following code sets up a window, sets up a timer to poll for events, and, over time, enqueues render updates:

#include <dispatch/dispatch.h>
#include <GL/glfw.h>

float t=0;

int main(void)
{
    dispatch_async(dispatch_get_main_queue(), ^{
        glfwInit();
        glfwDisable(GLFW_AUTO_POLL_EVENTS);
        glfwOpenWindow(320,200,8,8,8,8,8,0,GLFW_WINDOW);
    });

    // Periodically process window events --- this isn't working.
    dispatch_source_t windowEventTimer;
    windowEventTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    uint64_t nanoseconds = 100 * NSEC_PER_MSEC;
    dispatch_source_set_timer(windowEventTimer, dispatch_time(DISPATCH_TIME_NOW, nanoseconds), nanoseconds, 0);
    dispatch_source_set_event_handler(windowEventTimer, ^{
        glfwPollEvents();
    });
    dispatch_resume(windowEventTimer);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        for(int i=0;i<200;++i)
        {
            // Enqueue a rendering update.
            dispatch_async(dispatch_get_main_queue(), ^{
                glClearColor (0.2f, 0.2f, 0.4f, 1.0f);
                glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

                glColor3f (1.0, 0.7, 0.7); 
                glBegin( GL_LINES );
                    glVertex3f(0,0,0);
                    glVertex3f(t+=0.02,.1,0);
                glEnd();

                glfwSwapBuffers();
            });
            // Wait a bit, to simulate complex calculations.
            sleep(1);
        }
    });

    dispatch_main();
}

The animation updates as expected, but the window frame does not draw, and the window does not respond to events.

Community
  • 1
  • 1
smokris
  • 11,740
  • 2
  • 39
  • 59
  • 1
    GLFW gives you the freedom to control your event loop; you threw that freedom away by *making it a loop*. You cannot simply regurgitate some code into libdispatch and expect everything to work. You have to *think* about what it is you're trying to do. But since you haven't said what it is you're trying to accomplish (besides using OpenGL and libdispatch together), we can't really help you. What exactly are you trying to do with libdispatch and OpenGL? – Nicol Bolas Sep 24 '12 at 18:10
  • 1
    That doesn't exactly clear things up. Do you want other things to be dispatched while this is going on? How are you dispatching across threads? Etc. – Nicol Bolas Sep 24 '12 at 18:28
  • 1
    The overall application architecture is too complex to get into in the 600 characters I have here, but, basically: I have some code that does complex calculations and updates infrequently compared to vertical refresh. I would eventually like to have this code, when it's done with a set of calculations, enqueue a block that draws new content to the GL context, swaps the doublebuffer, then returns. And I'd like the window to be processing events in the meantime (between when redraw blocks are enqueued). This all works fine already, except for the window-processing-events bit. – smokris Sep 24 '12 at 18:38
  • My question was attempting to distill the problem down to the simplest form that exhibited the problem. Maybe it was too simple to be useful. I just replaced the question based on your advice. – smokris Sep 24 '12 at 18:52

1 Answers1

3

Digging through the GLFW source, I think I found the problem: the runloop of the Cocoa window created by GLFW needs to execute from Thread 0, but GLFW does not ensure that _glfwPlatformPollEvents() happens on Thread 0. (Identical symptoms were reported on this question about executing a Cocoa GUI on a thread other than 0.)

A workaround is to use the same private interface CoreFoundation uses to process the main libdispatch queue from inside a CFRunLoop.

If I replace the dispatch_main() call in the above code with this:

while(1)
{
    _dispatch_main_queue_callback_4CF(NULL);
    usleep(10000);
}

...it works as expected — the window frame draws, and the window processes events.


Trying to improve this hacky situation, I:

Community
  • 1
  • 1
smokris
  • 11,740
  • 2
  • 39
  • 59