我有两个文件,一个是主文件(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?
答案 0 :(得分:0)
在SDL_PushEvent上的SDL Wiki说它是线程安全的,所以我假设从其他线程调用它是好的。但是,它说您需要先调用SDL_RegisterEvents
来获取适合用作特定于应用程序的事件的事件ID,然后使用它来推送您的事件。
您的代码中不清楚这一点,您打电话给SDL_RegisterEvents
吗?这可能是问题所在。另外,如果您在初始化视频的同一个线程上推送事件,您是否检查过它是否有效?此测试将确保问题与线程无关。