【问题标题】:SDL2 Create Texture from different thread on OSXSDL2 从 OSX 上的不同线程创建纹理
【发布时间】:2014-05-03 04:41:17
【问题描述】:

我正在尝试在加载屏幕的单独线程中为 SDL2 程序加载纹理。我的代码看起来像这样

int batchLoad(void *ptr) {
loop through resources
    SDL_LockMutex(renderMutex);

        SDL_Texture *texture = NULL;

    SDL_Surface *surface = IMG_Load(("../resources/" + fileName).c_str());
    if (surface) {
    texture = SDL_CreateTextureFromSurface(renderer, surface);
    SDL_FreeSurface(surface);
    }
    SDL_UnlockMutex(renderMutex);

        // store texture

return 0;
}

void LoadingScreen::loadResources() {
// do some stuff

renderMutex = SDL_CreateMutex();

ScreenMap screenMap;
    // init with data
    SDL_Thread* load = SDL_CreateThread(batchLoad, "batchLoad", &screenMap);

while loading {
    // do work

    SDL_LockMutex(renderMutex);

    SDL_RenderClear(renderer);
    SDL_RenderCopy(renderer, white, NULL, NULL);

    // draw stuff

    SDL_RenderPresent(renderer);
    SDL_UnlockMutex(renderMutex);
}

SDL_WaitThread(load, NULL);
SDL_DestroyMutex(renderMutex);
SDL_DestroyMutex(satMutex);

在 Windows 上,这工作得非常好,但在 OSX 上,我在 CreateTextureFromSurface 调用时遇到错误。它出现空指针错误的段错误。这是 osx 问题报告。

Thread 10 Crashed:: batchLoad
0   libGL.dylib                     0x00007fff885ead32 glGenTextures + 18

Thread 10 crashed with X86 Thread State (64-bit):
rax: 0x0000000000000000  rbx: 0x00007ff913c37ad0  rcx: 0x0000000000000001  rdx: 0x00007ff913c37b50
rdi: 0x0000000000000001  rsi: 0x00007ff913c37b50  rbp: 0x00000001157ae4d0  rsp: 0x00000001157ae4d0
r8: 0x0000000000000004   r9: 0x00007ff913c00000  r10: 0x0000000023f4e094  r11: 0x000000000abea012
r12: 0x00007ff913d1e3b0  r13: 0x00007ff913d1e3b0  r14: 0x000000000000001a  r15: 0x0000000000000022
rip: 0x00007fff885ead32  rfl: 0x0000000000010246  cr2: 0x0000000000000000

和 lldb

* thread #9: tid = 0xee08, 0x00007fff885ead32 libGL.dylib`glGenTextures + 18, name = 'batchLoad', stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
frame #0: 0x00007fff885ead32 libGL.dylib`glGenTextures + 18
libGL.dylib`glGenTextures + 18:
-> 0x7fff885ead32:  movq   (%rax), %rdi
   0x7fff885ead35:  movq   0x318(%rax), %rax
   0x7fff885ead3c:  movl   %ecx, %esi
   0x7fff885ead3e:  popq   %rbp

当我注释掉所有线程内容并正常调用批处理加载时,没有错误,所以我认为必须存在一些并发问题。但是我对所有渲染器调用都使用了互斥锁,所以我不确定问题可能是什么。然后我也不知道为什么它在 Windows 上可以正常工作,但在 OSX 上不行

【问题讨论】:

  • 我不知道答案,但它确实没有段错误,您可以像处理表面一样,在存储它之前测试它是否为 NULL。只是一点点改进,但​​不是答案抱歉。
  • 问题是在 SDL_CreateTextureFromSurface 调用期间出现了段错误。所以我什至无法检查存储到纹理中的值

标签: c++ multithreading macos sdl-2


【解决方案1】:

由于 OpenGL 与多线程相关的规则,渲染器 API 不能从多个线程(无论是否执行任何锁定)调用。 This warning is mentioned on the CategoryRender page 并且有一个指向 bug report 的链接,您可以在其中阅读有关为什么会这样以及如何解决它的更多详细信息。

最简单的解决方法是在某个后台线程上加载表面,然后将其交给渲染器线程以加载到纹理中。

【讨论】:

  • 酷,我现在就试试看,如果可行,就接受这个答案。谢谢!
猜你喜欢
  • 2018-11-04
  • 1970-01-01
  • 2014-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多