<div style="line-height:1.7;color:#000000;font-size:14px;font-family:Arial"><pre><div>Hi Pekka£º</div><div><br></div><div>Sorry to take you some time. It's still this issue.</div><div>I made a test that using 'pthread' to created another thread, and then created the display in the child thread.</div><div>But program was blocked when connecting to a server(<span style="line-height: 23.8px; color: rgb(0, 0, 0);">wl_display_connect</span><span style="line-height: 1.7;">). It should be pending according to log.</span></div><div>However, I called the <span style="line-height: 23.8px;">renderFrames() in main thread, it</span> ran correctly and displayed the triangle.</div><div><span style="line-height: 1.7;">Could you tell me what causes the issue happend. </span></div><div><br></div><div><br></div><div><span style="line-height: 23.8px;">void</span><span style="line-height: 1.7; color: rgb(192, 192, 192);"> </span><span style="line-height: 1.7;">SurfaceManagerClient</span><span style="line-height: 1.7;">::</span><span style="line-height: 1.7;">initializeThread</span><span style="line-height: 1.7;">()</span></div><pre style="margin-top: 0px; margin-bottom: 0px;">{</pre><pre style="margin-top: 0px; margin-bottom: 0px;"><span style="line-height: 1.7;" class="">    pthread_t lifeThread;</span></pre><div>    <span style="line-height: 1.7;" class="">pthread_create(&lifeThread, NULL, &SurfaceManagerClient::renderFrames, NULL);  </span>  </div><div>}</div><div><br></div><div><pre style="margin-top: 0px; margin-bottom: 0px;"><span style="color: rgb(0, 0, 0);">void SurfaceManagerClient::renderFrames()</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;"><span style="color: rgb(0, 0, 0);">{</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">struct sigaction sigint;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">struct display display = { 0 };</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">struct window  window  = { 0 };</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">int i, ret = 0;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">  </pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">window.display = &display;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">display.window = &window;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">window.window_size.width  = 250;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">window.window_size.height = 250;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">window.buffer_size = 32;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">window.frame_sync = 1;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">for (i = 1; i < m_argc; i++) {</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">        <span style="color: rgb(0, 0, 0);">if (strcmp("-f", m_argv[i]) == 0)</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">            <span style="color: rgb(0, 0, 0);">window.fullscreen = 1;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">        <span style="color: rgb(0, 0, 0);">else if (strcmp("-o", m_argv[i]) == 0)</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">            <span style="color: rgb(0, 0, 0);">window.opaque = 1;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">        <span style="color: rgb(0, 0, 0);">else if (strcmp("-s", m_argv[i]) == 0)</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">            <span style="color: rgb(0, 0, 0);">window.buffer_size = 16;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">        <span style="color: rgb(0, 0, 0);">else if (strcmp("-b", m_argv[i]) == 0)</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">            <span style="color: rgb(0, 0, 0);">window.frame_sync = 0;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">        <span style="color: rgb(0, 0, 0);">else if (strcmp("-h", m_argv[i]) == 0)</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">            <span style="color: rgb(0, 0, 0);">usage(EXIT_SUCCESS);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">        <span style="color: rgb(0, 0, 0);">else</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">            <span style="color: rgb(0, 0, 0);">usage(EXIT_FAILURE);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">}</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;"><span style=" color:#c0c0c0;">    </span><span style="color: rgb(255, 0, 0);">display.display = wl_display_connect(NULL);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;"><span style=" color:#c0c0c0;">    </span><span style="color: rgb(0, 0, 0);">assert(display.display);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">display.registry = wl_display_get_registry(display.display);</span></pre>
<pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">wl_registry_add_listener(display.registry, <span style="color: rgb(0, 0, 0); line-height: 1.7;">&registry_listener, &display);</span></span></pre><pre style="margin-top: 0px; margin-bottom: 0px;"><br></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">int a = wl_display_dispatch(display.display);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">init_egl(&display, &window);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">create_surface(&window);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">init_gl(&window);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">display.cursor_surface = <span style="color: rgb(0, 0, 0); line-height: 1.7;">wl_compositor_create_surface(display.compositor);</span></span></pre><pre style="margin-top: 0px; margin-bottom: 0px;"><span style="line-height: 1.7; color: rgb(0, 0, 0);"><br></span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">sigint.sa_handler = signal_int;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">sigemptyset(&sigint.sa_mask);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">sigint.sa_flags = SA_RESETHAND;</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">sigaction(SIGINT, &sigint, NULL);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;"><br></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">while (running && ret != -1) {</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">        <span style="color: rgb(0, 0, 0);">wl_display_dispatch_pending(display.display);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">        <span style="color: rgb(0, 0, 0);">redraw(&window, NULL, 0);</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    <span style="color: rgb(0, 0, 0);">}</span></pre><pre style="margin-top: 0px; margin-bottom: 0px;">    fprintf(stderr, "simple-egl exiting\n");
    destroy_surface(&window);
</pre></div></pre><pre><div><pre style="margin-top: 0px; margin-bottom: 0px;">    fini_egl(&display);</pre></div></pre><pre><div><pre style="margin-top: 0px; margin-bottom: 0px;"> wl_surface_destroy(display.cursor_surface);
        if (display.cursor_theme)
                wl_cursor_theme_destroy(display.cursor_theme);

        if (display.shell)
                xdg_shell_destroy(display.shell);

        if (display.ivi_application)
                ivi_application_destroy(display.ivi_application);

        if (display.compositor)
                wl_compositor_destroy(display.compositor);

        wl_registry_destroy(display.registry);
        wl_display_flush(display.display);
        wl_display_disconnect(display.display);

        return 0;</pre><pre style="margin-top: 0px; margin-bottom: 0px;"><span style="color: rgb(0, 0, 0);">}</span></pre></div><div>
</div><div>Best regards,</div><div>Anthenony</div><div><br></div>>Oh indeed, sorry for my confusion. First, some general background
>information:
>
>eglSwapBuffers() counts as a Wayland protocol call, because it is
>guaranteed to call wl_surface.commit before it returns and with the
>newly rendered buffer attached, and it will also wait for
>wl_buffer.release events if necessary, and by default it also waits for
>wl_surface.frame callbacks to return.
>
>Here is what I wrote about EGL elsewhere:
>
>    eglSwapBuffers will be waiting for the previous eglSwapBuffers'
>    frame callback and only if it has not arrived already for the
>    particular surface. If you call eglSwapBuffers as a response to
>    receiving your own copy of the frame callback or later,
>    eglSwapBuffers will never block.
>
>    To be more precise, wait for the frame callback happens on the
>    eglSwapBuffers *after* the current one as I explained above,
>    and waits for wl_buffer.releases happen at the first draw call
>    that would need a buffer to draw into if necessary.
>
>    Those are the two orthogonal throttling mechanisms in Mesa.
>    Setting swap interval to 0 will prevent waits for the frame
>    callbacks, but not for buffer releases, because Mesa does not
>    want to potentially allocate an unlimited number of buffers in
>    case the server is slow to send out releases (which would imply
>    your whole system is already hosed anyway, so putting even more
>    pressure to it would only make things worse).
>
>The above describes the expected behaviour of EGL. Bugs, which we know
>to be around, are another matter.
>
>Do note, that I am only talking about Mesa and what a proper EGL
>implementation would do. If you are using any properietary EGL
>implementation, especially Vivante, you might be in trouble.
>
>Other things you must take care of are:
>
>- every thread where you want Wayland events dispatched must have its
>  own wl_event_queue (Mesa EGL creates one for itself)
>
>- you must use the wl_display_prepare_read() API of libwayland-client
>  in all callers of libwayland-client properly
>
>- Pay attention to all bugs linked from
>  https://bugs.freedesktop.org/show_bug.cgi?id=91769 ,
>  particularly https://bugs.freedesktop.org/show_bug.cgi?id=91273 which
>  also requires a fix in the EGL implementation (for Mesa, see
>  https://lists.freedesktop.org/archives/mesa-dev/2016-May/115617.html
>  for a patch that does not seem to have been even merged yet).
>
>In general, Wayland functions are *not* meant for controlling things
>across thread boundaries. It is safe to send requests from multiple
>threads, but you are still responsible for ordering them correctly
>yourself in cases where the order matters.
>
>If this gives you the impression that using threads with EGL/Wayland in
>particular is rare and not really tested, you are right. I do not know
>of any good code examples, maybe others have some?
>
>You say you are blocked in eglGetDisplay(). I have not heard of that
>before. Which EGL implementation is that? If it is not Mesa, and you
>cannot reproduce the problem with Mesa, then I suspect you have to
>contact your EGL vendor about it.
>
>
>Thanks,
>pq
</pre></div><br><br><span title="neteasefooter"><p> </p></span>