2014-05-03 41 views
2

我試圖在加載屏幕的單獨線程中爲SDL2程序加載紋理。我的代碼看起來是這樣的SDL2從OSX上的不同線程創建紋理

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上正常工作

+0

我不知道這個問題,但只是如此,它可以解決段錯誤問題,您可以像存儲表面一樣,在存儲之前測試它是否爲NULL。只是一個小改進,但不是答案抱歉。 – jofra

+0

問題是在SDL_CreateTextureFromSurface調用期間發生segfaults。所以我甚至無法檢查存儲到紋理中的值 – Donovan

回答

2

由於OpenGL的規則,渲染器API並不旨在從多個線程中調用(不管是否進行任何鎖定)涉及多線程。 This warning is mentioned on the CategoryRender page,並有一個鏈接到bug report,你可以在這裏閱讀更多關於爲什麼這樣的方式以及如何解決它的細節。

最簡單的解決方法是在某個後臺線程上加載表面,然後將其交給渲染器線程加載到紋理中。

+0

很酷,我現在試試看,如果它有效,接受這個答案。謝謝! – Donovan