SDL2在SDL_RenderClear()中卡住
SDL2 stucks in SDL_RenderClear()
我有两个文件,一个是主文件(main.cpp),另一个是多线程文件(threads.cpp)。我使用SDL_PushEvent()在threads.cpp和SDL_PollEvent()在main.cpp。下面是我的示例代码的逻辑。
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是找到的,但是当我创建两个线程来运行push_event时,SDL线程被阻塞了。
问题是硬件即GPU吗?
SDL Wiki上的SDL_PushEvent说它是线程安全的,所以我假设从其他线程调用它是可以的。但是,这里说您需要首先调用SDL_RegisterEvents
以获得适合用作应用程序特定事件的事件ID,然后使用它来推送您的事件。
从你的代码中看不清楚,你是在调用SDL_RegisterEvents
吗?这可能就是问题所在。另外,如果你在初始化视频的同一线程上推送事件,你是否检查过它是否有效?这个测试将确保问题与线程无关。
相关文章:
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- SDL 窗口不会弹出
- SDL 操纵杆按钮按下/C++
- VSCode IntelliSense无法识别SDL框架的SDL_image扩展库
- C++/SDL "initial value of reference to a non-const must be an lvalue"
- SDL 映像:无法打开映像,仅显示错误消息
- 如何在 3D OpenGL 场景上绘制 SDL 2D 矩形?
- "Undefined symbols for architecture x86_64" 在 SDL 2 (macOS) 中
- 为什么 SDL 在 Mac 上比 Linux 慢得多?
- 在 OSX 上打开 SDL 窗口时不要打开终端窗口
- SDL + OpenGL ES 2.0 使用着色器显示纹理
- SDL GPU 为什么将两个图像分成两个单独的循环更快?
- 在 cmake 中找不到 SDL 库
- SDL/C++: 如何平滑但随机地移动矩形?
- 如何与 SDL 库链接?
- 为什么我的C++代码不呈现 SDL 矩形?
- 为什么要在初始化SDL之前在SDL中声明指针
- C++/SDL 如何覆盖数组?
- 在 SDL 中水平减小静态图像进度条