protected void runLoop() {
        // If a restart is required, lets recreate the context.
        if (needRestart.getAndSet(false)) {
            restartContext();
        }

        if (!created.get()) {
            throw new IllegalStateException();
        }

        listener.update();

        // All this does is call glfwSwapBuffers().
        // If the canvas is not active, there's no need to waste time
        // doing that.
        if (renderable.get()) {
            try {
                // If type is 'Canvas'; lwjgl-awt takes care of swap buffers.
                if ((type != Type.Canvas) && allowSwapBuffers && autoFlush) {
                    // calls swap buffers, etc.
                    glfwSwapBuffers(window);
                }
            } catch (Throwable ex) {
                listener.handleError("Error while swapping buffers", ex);
            }
        }

        // Subclasses just call GLObjectManager. Clean up objects here.
        // It is safe ... for now.
        if (renderer != null) {
            renderer.postFrame();
        }

        if (autoFlush) {
            if (frameRateLimit != getSettings().getFrameRate()) {
                setFrameRateLimit(getSettings().getFrameRate());
            }
        } else if (frameRateLimit != 20) {
            setFrameRateLimit(20);
        }

        Sync.sync(frameRateLimit);

        glfwPollEvents();
    }
execute one iteration of the render loop in the OpenGL thread
jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglWindow.java