【问题标题】:GLX animation slower than expectedGLX 动画比预期慢
【发布时间】:2016-08-19 15:17:20
【问题描述】:

我有一个使用 XCB 和 openGL 的应用程序。一开始,我选择了一个带有以下属性的framebuffer配置:

const int attributes[] = {GLX_BUFFER_SIZE, 32, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, True, GLX_RENDER_TYPE, GLX_RGBA_BIT, None};
fb_configs = glXChooseFBConfig(display, screen_index, attributes, &fb_configs_count);

我运行了一个简单的动画,它应该持续固定的持续时间(1 秒),但在屏幕上显示它需要更长的时间(大约 5 秒)。添加日志显示进度值后,我发现实际循环仅持续1s。

struct timeval start; // start time of the animation
gettimeofday(&start, 0);

while (1)
{
    double progress = timer_progress(&start);
    if (progress > 1.0)
        break; // end the animation

    draw(progress);
    glXSwapBuffers(display, drawable);

    xcb_generic_event_t *event = xcb_poll_for_event(connection);
    if (!event)
    {
        usleep(1000);
        continue;
    }

    switch (event->response_type & ~0x80)
    {
    case XCB_EXPOSE:
    default:
        free(event);
        continue;
    }
}

我不确定到底发生了什么。我想在每次迭代中glXSwapBuffers() 将用于绘图的 opengl 命令排入队列,并且在循环结束时它们中的大多数尚未执行。

调整usleep() 的参数除了使动画不那么平滑或使动画变慢之外没有任何作用。当我切换到单缓冲时,问题就消失了(但我遇到了与单缓冲相关的问题)。

似乎我做的不对,但我不知道是什么。

【问题讨论】:

    标签: opengl xcb glx


    【解决方案1】:

    glXSwapBuffers 的确切计时行为对每个实现都是开放的。 NVidia 和 fglrx 选择阻止 glXSwapBuffers 直到 V-Sync(如果启用了 V-Sync),Mesa 和 Intel 选择立即返回并阻止下一个不再适合命令队列的调用,其中调用会修改后面在 V-Sync 暂停之前的缓冲区。

    但是,如果您希望动画具有精确的长度,那么具有固定帧数和执行延迟的循环将不起作用。相反,您应该尽可能快地重绘(并且仅使用延迟来限制您的绘图速率)。动画应该按照实际绘制迭代之间经过的实际时间而不是固定时间步长进行(这与实际上应该使用固定时间步长的游戏循环形成对比,尽管速度比绘制快得多)。

    最后但同样重要的是,您不得使用gettimeofday 来控制动画。 gettimeofday 报告挂钟时间,它可能会跳跃、减速或加速,甚至倒退。请改用高精度计时器 (clock_gettime(CLOCK_MONOTONIC, …))。

    【讨论】:

    • 我使用延迟只是为了限制绘制速率。 timer_progress() 返回自 start 以来经过的时间,draw() 使用该值。
    猜你喜欢
    • 2012-09-29
    • 2012-03-22
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    相关资源
    最近更新 更多