SDL2在子线程中SDL_DestroyWindow时发生阻塞

方法一:重新编译SDL2源码,把阻塞的函数屏蔽掉

void SDL_DestroyWindow(SDL_Window * window)
{
    SDL_VideoDisplay *display;

    CHECK_WINDOW_MAGIC(window,);

    window->is_destroying = SDL_TRUE;

    /* Restore video mode, etc. */
   //SDL_HideWindow(window);

    /* Make sure this window no longer has focus */
    if (SDL_GetKeyboardFocus() == window) {
        SDL_SetKeyboardFocus(NULL);
    }
    if (SDL_GetMouseFocus() == window) {
        SDL_SetMouseFocus(NULL);
    }

    /* make no context current if this is the current context window. */
    if (window->flags & SDL_WINDOW_OPENGL) {
        if (_this->current_glwin == window) {
            SDL_GL_MakeCurrent(window, NULL);
        }
    }

    if (window->surface) {
        window->surface->flags &= ~SDL_DONTFREE;
        SDL_FreeSurface(window->surface);
        window->surface = NULL;
        window->surface_valid = SDL_FALSE;
    }
    if (_this->DestroyWindowFramebuffer) {
        _this->DestroyWindowFramebuffer(_this, window);
    }
    if (_this->DestroyWindow) {
        _this->DestroyWindow(_this, window);
    }
    if (window->flags & SDL_WINDOW_OPENGL) {
        SDL_GL_UnloadLibrary();
    }
    if (window->flags & SDL_WINDOW_VULKAN) {
        SDL_Vulkan_UnloadLibrary();
    }

    display = SDL_GetDisplayForWindow(window);
    if (display->fullscreen_window == window) {
        display->fullscreen_window = NULL;
    }

    /* Now invalidate magic */
    window->magic = NULL;

    /* Free memory associated with the window */
    SDL_free(window->title);
    SDL_FreeSurface(window->icon);
    SDL_free(window->gamma);
    while (window->data) {
        SDL_WindowUserData *data = window->data;

        window->data = data->next;
        SDL_free(data->name);
        SDL_free(data);
    }

    /* Unlink the window from the list */
    if (window->next) {
        window->next->prev = window->prev;
    }
    if (window->prev) {
        window->prev->next = window->next;
    } else {
        _this->windows = window->next;
    }

    SDL_free(window);
}

我的SDL2的初始化和渲染都是在子线程。
当调用SDL_DestroyWindow阻塞在第四行SDL_HideWindow(window)。
再继续跟踪发现是WINAPI发生的阻塞。

WINUSERAPI BOOL WINAPI ShowWindow( _In_ HWND hWnd, _In_ int nCmdShow);

解决办法:
SDL_HideWindow(window);屏蔽注释掉,重新编译。跳过阻塞的这个过程。(这种解决办法投机取巧)

方法二:窗口变量在主线程创建并传入子线程,子线程中建立新的渲染器,用这个渲染器渲染主线程的窗口变量

方法三(针对QT):子线程负责解码,GUI线程负责渲染
子线程把解码好的数据通过信号传递给GUI程进行渲染,整个程序的生存周期只在主线程进行一次SDL2初始化和释放。例子:https://blog.csdn.net/asdasfdgdhh/article/details/116160009

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值