SDL2卡在SDL_RenderClear()中

时间:2014-08-05 07:56:59

标签: android c++ multithreading sdl-2

我有两个文件,一个是主文件(main.cpp),另一个是多线程(threads.cpp)。 我在threads.cpp中使用 SDL_PushEvent(),在main.cpp中使用 SDL_PollEvent()。 下面是我的示例代码的逻辑。

的main.cpp

bool Init() {
    if (SDL_Init(SDL_INIT_VIDEO) < 0)
        return false;

    SDL_DisplayMode mode;
    SDL_GetDisplayMode(0, 0, &mode);
    this->win_width = mode.w;
    this->win_height = mode.h;

    this->win = SDL_CreateWindow(NULL, 0, 0, win_width, win_height, SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
    if (this->win == NULL) {
        LOGE("[Init] SDL Window Created failed : %s", SDL_GetError());
        return false;
    }

    this->renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);
    if (this->renderer == NULL) {
        LOGE("[Init] SDL Renderer Created failed : %s", SDL_GetError());
        return false;
    }

    this->bmp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, win_width, win_height);
    if (this->bmp == NULL) {
        LOGE("[Init] SDL Texture Created failed : %s", SDL_GetError());
        return false;
    }

    return true;
}

void DisplayEvent (SDL_Event e) {
    FrameObject obj = *(FrameObject*) e.user.data1;

    SDL_Rect rect;
    rect.x = rect.y = 0;
    rect.w = obj.frameWidth;
    rect.h = obj.frameHeight;

    int r = SDL_UpdateTexture(this->bmp, NULL, obj.FrameData.RGB, rect.w*2);
    LOGI("[DisplayEvent] - UpdateTexture");

    // Reneder this Frame
    SDL_RenderClear(this->renderer);
    LOGI("[DisplayEvent] - RenderClear");
    SDL_RenderCopy(this->renderer, this->bmp, NULL, &rect);
    LOGI("[DisplayEvent] - RenderCopy");
    SDL_RenderPresent(this->renderer);
    LOGI("[DisplayEvent] - RenderPresent");
}

int main (int argc, char **argv) {
    Init();

    while (!quit) {
        SDL_Event e;
        // Event Polling
        while (SDL_PollEvent(&e)) {
            switch (e.type) {
                case MY_EVENT:
                    LOGI("[main] - Get MY_EVENT");
                    DisplayEvent(e);
                    LOGI("[main] - %s more MY_EVENT", SDL_HasEvent(MY_EVENT) ? "Has" : "Hasn't");
                    break;
                default:
                    break;
            }
        }
    }

    SDL_Quit();
}

threads.cpp

void* push_event(void *arg) {
    FrameObject obj = (FrameObject*) arg;
    while (!quit) {
        SDL_Event event;
        SDL_zero(event);
        event.type = MY_EVENT;
        event.user.data1 = obj;
        event.user.data2 = 0;
        if (SDL_PushEvent(&event) == 1) LOGI("[push_event] - Push MY_EVENT");
        else LOGE("[push_event] - Event Push Error : %s", SDL_GetError());

        sleep(1);
    }
}

修改 我添加了更多示例代码。我发现问题并没有遗漏SDL事件。问题是SDL线程(主线程)在SDL_RenderClear()处被阻止。

日志消息输出“[DisplayEvent] - UpdateTexture”但不打印“[DisplayEvent] - RenderClear”。有点奇怪。对于创建单线程来运行push_event是find,但是当我创建两个线程来运行push_event时,SDL线程被阻塞。

问题是硬件即GPU?

1 个答案:

答案 0 :(得分:0)

SDL_PushEvent上的SDL Wiki说它是线程安全的,所以我假设从其他线程调用它是好的。但是,它说您需要先调用SDL_RegisterEvents来获取适合用作特定于应用程序的事件的事件ID,然后使用它来推送您的事件。

您的代码中不清楚这一点,您打电话给SDL_RegisterEvents吗?这可能是问题所在。另外,如果您在初始化视频的同一个线程上推送事件,您是否检查过它是否有效?此测试将确保问题与线程无关。