SDL_PollEvent()在空闲时口吃? [英] SDL_PollEvent() stuttering while idle?

查看:77
本文介绍了SDL_PollEvent()在空闲时口吃?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用SDL2整理了C ++中一个非常基本的游戏循环,我注意到每隔几秒钟,SDL_PollEvent似乎异常缓慢,即使什么也没发生。

I've cobbled together a very basic game loop in C++ using SDL2, and I've noticed that every few seconds, SDL_PollEvent seems to be unusually slow, even when nothing is happening.

我将我的deltaTime发送到控制台的每个循环,以及SDL_PollEvent滞后的周期大约有100毫秒的差异。我已经确认可以通过移动计时器来实现此功能,但是我不确定在哪里可以进一步诊断问题。

I sent my deltaTime to console every loop, and its about 100ms difference on the cycles that SDL_PollEvent is lagging. I've already confirmed that it's something with this function by moving my timers around, but I'm not sure where to diagnose the issue further.

我的循环:

while (!quit) {

    uint32_t startTime = SDL_GetTicks();

    while (SDL_PollEvent(&e) != 0) {
    std::cout << "Event: "<< e.type << std::endl; // Added later, read update
        if (e.type == SDL_QUIT) {
            quit = true;
        }
    }

    if (engine.AllowUpdate()) { // Restricts updates to every 20ms
        GameState::Update(); 
    }


    engine.rMan.BeginRender();
    //^v Literally just SDL_RenderClear and SDL_RenderPresent
    engine.rMan.FinishRender();

    engine.deltaTime = SDL_GetTicks() - startTime;
    std::cout << std::setw(10) << engine.deltaTime;
}

没有Vsync的控制台输出,请注意106。这是我的滞后: href = https://i.stack.imgur.com/KxhC4.png rel = noreferrer>

Console output with no Vsync, note the 106. That's my lag:

使用Vsync。请注意,滞后后的增量略短。不知道为什么:

With Vsync. Note that the delta following the lag is slightly shorter. Not sure why:

我还注意到,即使我没有进行调试也没有出现此问题,在至少另一台机器上。

I've also noticed that this issue happens even if I'm not debugging, and is not present on at least one other machine. Any suggestions on how to proceed would be very welcome.

编辑1:试图打印以管理所有正在排队的事件,以查看是否其中一个引起了该事件。问题。在上面的代码中添加了打印行。在出现延迟的时候似乎没有事件触发,否则我就处于空闲状态。

EDIT 1: Tried to print to console all events that were going through the queue to see if one of them was causing the issue. Added the print line to the code above. No events seemed to be firing at the times that there was lag, and I was otherwise idle.

编辑2:根据要求,使用C ++构建了一些可运行的代码在VS2017上使用SDL2-2.0.9的第14个:

EDIT 2: As requested, some runnable code, built with c++14 on VS2017 with SDL2-2.0.9:

#include <iostream>
#include <SDL.h>

void InitSDL();
void BuildWindow();
void BuildRenderer();

SDL_Window* window;
SDL_Renderer* renderer;

int main(int argc, char* args[]) {
    InitSDL();
    BuildWindow();
    BuildRenderer();
    bool quit = false;

    uint32_t deltaTime = 0;

    while (!quit) {
        uint32_t startTime = SDL_GetTicks();

        SDL_Event e;
        while (SDL_PollEvent(&e) != 0) {
            if (e.type == SDL_QUIT) {
                quit = true;
            }
        }
        deltaTime = SDL_GetTicks() - startTime;
        std::cout << deltaTime << std::endl;

        SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
        SDL_RenderClear(renderer);
        SDL_RenderPresent(renderer);
    }

    return 0;
}

void InitSDL() {
    Uint32 flags = SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS;
    SDL_Init(flags);
}

void BuildWindow() {
    window = SDL_CreateWindow
    ("SDL Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        800, 600, NULL);
}

void BuildRenderer() {
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC);
}

放在一起时,我注意到了一些事情:

While putting this together, I noticed a few things:

<打击> 1。没有SDL_RenderPresent ,就不会发生口吃。经过仔细检查后,情况似乎并非如此,但是SDL_RenderPresent似乎受到了口吃的影响。

1. The stutter did not occur without SDL_RenderPresent After double-checking, this does not appear to be the case, however, SDL_RenderPresent appears to be impacted by the stutter.


  1. 在SDL_PollEvent期间某处发生了与口吃相吻合的deltaTime的增加,这可以从deltaTime的分配位置得到证明

  1. The increase in deltaTime that coincides with the stutter appears to occur somewhere during SDL_PollEvent, as evidenced by where deltaTime is being assigned

第一个deltaTime总是更长,尽管我怀疑这与启动时触发的一些默认事件有关。

The first deltaTime is ALWAYS longer, though I suspect this has something to do with some default events firing on startup.

编辑3:多挖些东西。尝试仅在SDL_RenderPresent周围移动我的增量分配。

EDIT 3: Did a little more digging. Tried to move my delta assignment around just the SDL_RenderPresent.

示例代码段:

    SDL_Event e;
    while (SDL_PollEvent(&e) != 0) {
        std::cout << "Event: "<< e.type << std::endl;
        if (e.type == SDL_QUIT) {
            quit = true;
        }
    }

    uint32_t startTime = SDL_GetTicks();
    //SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    //SDL_RenderClear(renderer);
    SDL_RenderPresent(renderer);
    deltaTime = SDL_GetTicks() - startTime;
    std::cout << deltaTime << std::endl;

在启用vsync的情况下,获得以下控制台输出:

With vsync on, got the following console output:

编辑4:更多数据。好像断断续续地每3000ms发生一次。我的控制台输出的增量仅> 50ms。图片格式为:游戏循环次数| deltaTime | SDL_GetTicks()

EDIT 4: MORE DATA. Looks like the stutter is happening every 3000ms almost exactly. I had the console output just the deltas that were > 50ms. Format in image is: # of game loop cycles | deltaTime | SDL_GetTicks()

我也认为这是硬件问题,因为我没有这个问题在另一台机器上,我还下载了其他一些开源SDL游戏,并且遇到了相同的断断续续的情况,相距3000毫秒。我还在Windows 10和Windows 7的相同硬件上看到相同的问题。除非有人认为有必要,否则我不会发布我的规格,但是我已经通过看到相同的问题消除了专用GPU出现故障的可能性

I've also considered that this is a hardware problem, since I'm not having this issue on another machine, and I've also downloaded a few other open source SDL games and am experiencing the same stutter, 3000ms apart. I am also seeing the same problem on the same hardware in both Windows 10 and Windows 7. Not going to post my specs unless someone thinks it's necessary, but I've already eliminated the possibility of my dedicated GPU being at fault by seeing the same exact issue when running the game through RDP with my GPU removed.

编辑5:看起来滞后与USB设备有关。 SDL是否每隔3000毫秒或类似的时间对所有设备进行一次查找?

EDIT 5: Looks like the lag has something to do with USB devices. Does SDL do a lookup of all devices every 3000ms or something?

将GPU放回计算机后,我发现时滞大大减少了,我注意到唯一的与之前和之后的区别是我的USB耳机不再插入。

After putting my GPU back in my machine, I noticed the lag dropped significantly, and I noticed that the only difference from before and after was that my USB headset was no longer plugged in.

直觉上,我再次运行我的循环,这次要监视3ms以上的deltaTime。删除设备后,我观看了控制台的更改:

On a hunch, I ran my loop again, this time watching for any deltaTime over 3ms. I watched the console for changes as I removed devices:

尤里卡!有点。没有插入USB设备,deltaTime始终保持在3ms以下。我测试过的第二台计算机是一台笔记本电脑,因此没有插入USB设备。我回去,并使用相同的USB鼠标对其进行了测试,正如预期的那样,每隔3000毫秒我看到一个明显的结结。

Eureka! Sort of. With no USB devices plugged in, deltaTime remained below 3ms consistently. The secondary machine I tested on was a laptop, and thus had no USB devices plugged in. I went back, and tested it with the same USB mouse, and as expected, I saw a noticeable stutter every 3000ms.

因此,当前的问题是:USB设备如何引起这种卡顿?与(a)USB设备和(b)SDL_RenderPresent()相关的每3000ms SDL会做什么?

So the current question is: How can USB devices be causing this stuttering? What does SDL do every 3000ms that is related to (a) USB devices and (b) SDL_RenderPresent()?

推荐答案

I'我仍然不确定到底是什么引起了该问题,但它肯定与USB设备有关。设备插入的次数越多,延迟尖峰的时间就越长,并且几乎每隔3000ms就会发生一次。

I'm still not sure exactly what is causing the problem, but it certainly has something to do with USB devices. The more devices plugged in, the longer the latency spike, and it occurs almost every 3000ms exactly.

我从SDL2-2.0.9退回到SDL2-2.0.8 ,问题已停止。

I rolled back from SDL2-2.0.9 to SDL2-2.0.8, and the issue has stopped.

编辑:在 https://hg.libsdl.org/SDL/rev/9091b20040cf 似乎可以解决SDL2-2.0.9中的此问题。

Changeset found at https://hg.libsdl.org/SDL/rev/9091b20040cf appears to resolve this issue in SDL2-2.0.9.

这篇关于SDL_PollEvent()在空闲时口吃?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆