Python 将控制权从Pygame转移到SDL2导致CALayer异常 上下文

Python 将控制权从Pygame转移到SDL2导致CALayer异常 上下文,python,pygame,sdl,sdl-2,Python,Pygame,Sdl,Sdl 2,我从事认知科学,所以这个问题的背景很难表达。长话短说,我们有一个严重依赖PyGame的现存库;我们需要将SDL2用于特定的实验任务 我们的库在设计实验时扩展了一个基类Exp;它初始化PyGame,有一个简单且经过良好测试的准备序列,然后将控制权传递给实验者,以完成构成实验的一组抽象方法 目标:在切换时,杀死PyGame并切换到SDL2 问题:SDL2脚本下面的脚本在Exp环境之外使用时工作。但是,当它仅仅改变了一个小小的实验实现时,就会发生两件事: 我们正在使用SDL2加载的图像不会像SDL2窗

我从事认知科学,所以这个问题的背景很难表达。长话短说,我们有一个严重依赖PyGame的现存库;我们需要将SDL2用于特定的实验任务

我们的库在设计实验时扩展了一个基类Exp;它初始化PyGame,有一个简单且经过良好测试的准备序列,然后将控制权传递给实验者,以完成构成实验的一组抽象方法

目标:在切换时,杀死PyGame并切换到SDL2

问题:SDL2脚本下面的脚本在Exp环境之外使用时工作。但是,当它仅仅改变了一个小小的实验实现时,就会发生两件事:

我们正在使用SDL2加载的图像不会像SDL2窗口那样明显地绘制 引发异常:CALayer位置包含NaN:[NaN NaN] 当前可疑的Pygame和SDL2正在争夺两个名称空间,从程序启动时的终端输出可以看出:

objc[34300]: Class SDLTranslatorResponder is implemented in both /Library/Frameworks/SDL.framework/Versions/A/SDL and /Library/Frameworks/SDL2.framework/SDL2. One of the two will be used. Which one is undefined.
objc[34300]: Class SDLApplication is implemented in both /Library/Frameworks/SDL2.framework/SDL2 and /Library/Python/2.7/site-packages/pygame/sdlmain_osx.so. One of the two will be used. Which one is undefined.
下面是正在工作的外部脚本以及为在Exp上下文中实现它所做的小修改。最后,完整的错误输出在底部

任何关于这个问题的建议都将不胜感激

SDL2脚本 控制台输出 2014-10-16 15:15:18.366 Python[34300:d07]出现了一个未捕获的异常 提升2014-10-16 15:15:18.366 Python[34300:d07]加莱尔位置 包含NaN:[NaN NaN]2014-10-16 15:15:18.366 Python[34300:d07]0 CoreFoundation 0x00007fff8fba325c 异常预处理+172 1 libobjc.A.dylib 0x00007fff86dc3e75 objc_异常_抛出+43 2 CoreFoundation 0x00007fff8fba310c+[N异常上升:格式:][204 3夸脱核心 0x00007fff84cc425e\u Zn2CA512层设置定位器KNS\u 4VEC2 DEEB+158 4 石英芯0x00007fff84cc41b7-[CALayer 设置位置:+44 5夸脱芯 0x00007fff84cc5e97-[CALayer设置框架:+858 6应用套件 0x00007fff8e5e837e-[\n完整屏幕转换覆盖窗口 位置层]+1790 7应用套件 0x00007fff8e5e8e61-[\n完整屏幕转换覆盖窗口 startEnterFullScreenAnimationWithDuration:completionHandler:+55 8 应用套件0x00007fff8e5ead76 -[\u NSFullScreenTransition\u startFullScreenTransitionForCGWindow:targetFrame:duration:completionHandler:] +193 9应用套件0x00007fff8e5ecca6 \uuuu 89-[\uu NSFullScreenTransition\u PerformancerFullScreenMode动画:激活:自定义窗口:]\u块\u调用361 +1430 10 libxpc.dylib 0x00007fff84eafca2连接应答呼叫+47 11 libxpc.dylib 0x00007fff84eafc2e连接应答+36 12 libdispatch.dylib 0x00007fff869ab2ad _调度客户端调用+8 13 libdispatch.dylib 0x00007fff869b2f03调度主队列回调4CF+333 14 CoreFoundation 0x00007fff8fb0a679 __CFRUNLOOP\u正在为主调度队列+9 15 CoreFoundation 0x00007fff8fac5954 CFRUNLOOP运行提供服务 +1636 16 CoreFoundation 0x00007fff8fac50b5 CFRunLoopRunSpecific+309 17 HIToolbox 0x00007fff85ab9a0d RunCurrentEventLoopInMode+226 18 HIToolbox 0x00007fff85ab97b7接收NEXTEVENTCOMMON+479 19 HIToolbox 0x00007fff85ab95bc _blockuntinexteventmatchinglistinmodewithfilter+ 65 20应用套件0x00007fff8dd293de _DPSNextent+1434 21应用套件0x00007fff8dd28a2b-[N应用 下一个VentMatchingTask:untilDate:inMode:dequeue:+122 22 SDL 0x000000011023243c SDL\u软拉伸+7888 23 SDL 0x0000000110211efd SDL\U泵出口+38 24 SDL 0x00000001102120dd SDL\u事件状态+200 25 SDL 0x00000001102303f6 SDL_操纵杆安全状态+82 26操纵杆.so 0x000000011040313d joy_autoinit+42 27 Python 0x000000010ff18f72 PyObject_调用+101 28 Python 0x000000010ff9501f PyEval_callobjectwith关键字+93 29 base.so 0x0000000110207c47 init+279 30 Python 0x000000010ff921ef PyEval_EvalFrameEx+12338 31 Python 0x000000010ff8f093 PyEval_evalcodex+1641 32 Python 0x000000010ff36796 PyFunction_SetClosure+809 33 Python 0x000000010ff18f72 PyObject_调用+101 34 Python 0x000000010ff239a7 PyMethod_New+1200 35 Python 0x000000010ff18f72 PyObject_调用+101 36 Python 0x000000010ff92df5 PyEval_EvalFrameEx+15416 37 Python 0x000000010ff8f093 PyEval_evalcodex+1641 38 Python 0x000000010ff36796 PyFunction_SetClosure+809 39 Python 0x000000010ff18f72 PyObject_调用+101 40 Python 0x000000010ff239a7 PyMethod_New+1200 41 Python 0x000000010ff18f72 PyObject_调用+101 42 Python 0x000000010ff5e6ce_PyObje ct\U插槽比较+5565 43 Python 0x000000010ff5a184_PyType_Lookup+1343 44 Python 0x000000010ff18f72 PyObject_调用+101 45 Python 0x000000010ff92df5 PyEval_EvalFrameEx+15416 46 Python 0x000000010ff8f093 PyEval_evalcodex+1641 47 Python 0x000000010ff958c8_PyEval_SliceIndex+929 48 Python 0x000000010ff924d4 PyEval_EvalFrameEx+13079 49 Python 0x000000010ff8f093 PyEval_evalcodex+1641 50 Python 0x000000010ff36796 PyFunction_SetClosure+809 51 Python 0x000000010ff18f72 PyObject_调用+101 52 Python 0x000000010ff93395 PyEval_EvalFrameEx+16856 53 Python 0x000000010ff8f093 PyEval_evalcodex+1641 54 Python 0x000000010ff958c8_PyEval_SliceIndex+929 55 Python 0x000000010ff924d4 PyEval_EvalFrameEx+13079 56 Python 0x000000010ff8f093 PyEval_evalcodex+1641 57 Python 0x000000010ff36796 PyFunction_SetClosure+809 58 Python 0x000000010ff18f72 PyObject_调用+101 59 Python 0x000000010ff93395 PyEval_EvalFrameEx+16856 60 Python 0x000000010ff8f093 PyEval_evalcodex+1641 61 Python 0x000000010ff958c8_PyEval_SliceIndex+929 62 Python 0x000000010ff924d4 PyEval_EvalFrameEx+13079 63 Python 0x000000010ff8f093 PyEval\u evalcodex+1641 64 Python 0x000000010ff8ea24 PyEval_EvalCode+54 65 Python 0x000000010ffadc2c PyParser_ASTFromFile+306 66 Python 0x000000010ffadcd3 PyRun_FileExFlags+137 67 Python 0x000000010ffad821 PyRun\u SimpleFileXFLAGS+718 68 Python 0x000000010ffbe363 Py_Main+2995 69 libdyld.dylib 0x00007fff89e375fd启动+1 70??? 0x0000000000000002 0x0+2 2014-10-16 15:15:18.367 Python[34300:d07] ***由于未捕获异常“CALayerInvalidGeometry”,正在终止应用程序,原因:“CALayer位置包含NaN:[NaN 南]' ***第一次抛出调用堆栈:0 CoreFoundation 0x00007fff8fba325c\uu异常预处理+172 1 libobjc.A.dylib 0x00007fff86dc3e75 objc_异常_抛出+43 2 CoreFoundation 0x00007fff8fba310c+[N异常上升:格式:][204 3夸脱核心 0x00007fff84cc425e\u Zn2CA512层设置定位器KNS\u 4VEC2 DEEB+158 4 石英芯0x00007fff84cc41b7-[CALayer 设置位置:+44 5夸脱芯 0x00007fff84cc5e97-[CALayer设置框架:+858 6应用套件 0x00007fff8e5e837e-[\n完整屏幕转换覆盖窗口 位置层]+1790 7应用套件 0x00007fff8e5e8e61-[\n完整屏幕转换覆盖窗口 startEnterFullScreenAnimationWithDuration:completionHandler:+55 8 应用套件0x00007fff8e5ead76 -[\u NSFullScreenTransition\u startFullScreenTransitionForCGWindow:targetFrame:duration:completionHandler:] +193 9应用套件0x00007fff8e5ecca6 \uuuu 89-[\uu NSFullScreenTransition\u PerformancerFullScreenMode动画:激活:自定义窗口:]\u块\u调用361 +1430 10 libxpc.dylib 0x00007fff84eafca2连接应答呼叫+47 11 libxpc.dylib 0x00007fff84eafc2e连接应答+36 12 libdispatch.dylib 0x00007fff869ab2ad _调度客户端调用+8 13 libdispatch.dylib 0x00007fff869b2f03调度主队列回调4CF+333 14 CoreFoundation 0x00007fff8fb0a679 __CFRUNLOOP\u正在为\u主\u调度\u队列+9 15 CoreFoundation 0x00007fff8fac5954\u CFRUNLOOP运行提供服务 +1636 16 CoreFoundation 0x00007fff8fac50b5 CFRunLoopRunSpecific+309 17 HIToolbox 0x00007fff85ab9a0d RunCurrentEventLoopInMode+226 18 HIToolbox 0x00007fff85ab97b7接收NEXTEVENTCOMMON+479 19 HIToolbox 0x00007fff85ab95bc _blockuntinexteventmatchinglistinmodewithfilter+ 65 20应用套件0x00007fff8dd293de _DPSNextent+1434 21应用套件0x00007fff8dd28a2b-[N应用 下一个VentMatchingTask:untilDate:inMode:dequeue:+122 22 SDL 0x000000011023243c SDL\u软拉伸+7888 23 SDL 0x0000000110211efd SDL\U泵出口+38 24 SDL 0x00000001102120dd SDL\u事件状态+200 25 SDL 0x00000001102303f6 SDL_操纵杆安全状态+82 26操纵杆.so 0x000000011040313d joy_autoinit+42 27 Python 0x000000010ff18f72 PyObject_调用+101 28 Python 0x000000010ff9501f PyEval_callobjectwith关键字+93 29 base.so 0x0000000110207c47 init+279 30 Python 0x000000010ff921ef PyEval_EvalFrameEx+12338 31 Python 0x000000010ff8f093 PyEval_evalcodex+1641 32 Python 0x000000010ff36796 PyFunction_SetClosure+809 33 Python 0x000000010ff18f72 PyObject_调用+101 34 Python 0x000000010ff239a7 PyMethod_New+1200 35 Python 0x000000010ff18f72 PyObject_调用+101 36 Python 0x000000010ff92df5 PyEval_EvalFrameEx+15416 37 Python 0x000000010ff8f093 PyEval_evalcodex+1641 38 Pytho N 0x000000010ff36796 PyFunction_SetClosure+809 39 Python 0x000000010ff18f72 PyObject_调用+101 40 Python 0x000000010ff239a7 PyMethod_New+1200 41 Python 0x000000010ff18f72 PyObject_调用+101 42 Python 0x000000010ff5e6ce\u PyObject\u SlotCompare+5565 43 Python 0x000000010ff5a184_PyType_Lookup+1343 44 Python 0x000000010ff18f72 PyObject_调用+101 45 Python 0x000000010ff92df5 PyEval_EvalFrameEx+15416 46 Python 0x000000010ff8f093 PyEval_evalcodex+1641 47 Python 0x000000010ff958c8_PyEval_SliceIndex+929 48 Python 0x000000010ff924d4 PyEval_EvalFrameEx+13079 49 Python 0x000000010ff8f093 PyEval_evalcodex+1641 50 Python 0x000000010ff36796 PyFunction_SetClosure+809 51 Python 0x000000010ff18f72 PyObject_调用+101 52 Python 0x000000010ff93395 PyEval_EvalFrameEx+16856 53 Python 0x000000010ff8f093 PyEval_evalcodex+1641 54 Python 0x000000010ff958c8_PyEval_SliceIndex+929 55 Python 0x000000010ff924d4 PyEval_EvalFrameEx+13079 56 Python 0x000000010ff8f093 PyEval_evalcodex+1641 57 Python 0x000000010ff36796 PyFunction_SetClosure+809 58 Python 0x000000010ff18f72 PyObject_调用+101 59 Python 0x000000010ff93395 PyEval_EvalFrameEx+16856 60 Python 0x000000010ff8f093 PyEval_evalcodex+1641 61 Python 0x000000010ff958c8_PyEval_SliceIndex+929 62 Python 0x000000010ff924d4 PyEval_EvalFrameEx+13079 63 Python 0x000000010ff8f093 PyEval\u evalcodex+1641 64 Python 0x000000010ff8ea24 PyEval_EvalCode+54 65 Python 0x000000010ffadc2c PyParser_ASTFromFile+306 66 Python 0x000000010ffadcd3 PyRun_FileExFlags+137 67 Python 0x000000010ffad821 PyRun\u SimpleFileXFLAGS+718 68 Python 0x000000010ffbe363 Py_Main+2995 69 libdyld.dylib 0x00007fff89e375fd启动+1 70??? 0x0000000000000002 0x0+2 libc++abi.dylib:终止于 NSException类型的未捕获异常

进程已完成,退出代码为13


在咨询了一些内部的书呆子(他们确认了对我问题的评论)后,解决方案是:同时使用PyGame和SDL2通常比用SDL2替换PyGame需要更多的工作。不要这样做


把我的问题留着以防万一

您正在加载SDL1和SDL2;你不想那么做,是的。我知道。我希望有人能比我更容易搞出书呆子来,或者找个黑客或者做点什么。唉,唯一能绕过这个UB的黑客需要做的工作就是升级到pygame2和抛弃SDL1,这是你真正需要做的。是的,我承认这一点。所有的叹息。
import sdl2 
import sdl2.ext 
import numpy 
from PIL import Image 
import time 
import OpenGL.GL as gl
from scipy import misc
import os

stimDisplayRes = (1366,768) #pixel resolution of the stimDisplay    
imgs = []
img_path = "path/to/jpgs"
# this loop just grabs our images; works fine in both scripts
for x in range(1, 450):
    x = str(int(x * 2.5)).zfill(8)
    path = os.path.join(img_path, "{0}.jpg".format(x))
    imgs.append(numpy.array(Image.open(path)))


sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
stimDisplay = sdl2.ext.Window("Experiment", size=stimDisplayRes,position=(0,0),flags=sdl2.SDL_WINDOW_OPENGL|sdl2.SDL_WINDOW_SHOWN| sdl2.SDL_WINDOW_FULLSCREEN_DESKTOP |sdl2.SDL_RENDERER_ACCELERATED | sdl2.SDL_RENDERER_PRESENTVSYNC)
glContext = sdl2.SDL_GL_CreateContext(stimDisplay.window)
gl.glMatrixMode(gl.GL_PROJECTION)
gl.glLoadIdentity()
gl.glOrtho(0, stimDisplayRes[0],stimDisplayRes[1], 0, 0, 1)
gl.glMatrixMode(gl.GL_MODELVIEW)
gl.glDisable(gl.GL_DEPTH_TEST)

sdl2.SDL_PumpEvents() # to show the windows

time.sleep(1)

def blitNumpy(numpyArray,xLoc,yLoc,xCentered=True,yCentered=True):
    gl.glEnable(gl.GL_BLEND)
    gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
    ID = gl.glGenTextures(1)
    gl.glBindTexture(gl.GL_TEXTURE_2D, ID)
    gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_REPLACE);
    gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP)
    gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP)
    gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
    gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
    if len(numpyArray.shape)==3: #no alpha channel
        gl.glTexImage2D( gl.GL_TEXTURE_2D , 0 , gl.GL_RGBA , numpyArray.shape[1] , numpyArray.shape[0] , 0 , gl.GL_RGB , gl.GL_UNSIGNED_BYTE , numpyArray )
    elif len(numpyArray.shape)==4: #alpha channel
        gl.glTexImage2D( gl.GL_TEXTURE_2D , 0 , gl.GL_RGBA , numpyArray.shape[1] , numpyArray.shape[0] , 0 , gl.GL_RGBA , gl.GL_UNSIGNED_BYTE , numpyArray )
    gl.glEnable(gl.GL_TEXTURE_2D)
    gl.glBindTexture(gl.GL_TEXTURE_2D, ID)
    gl.glBegin(gl.GL_QUADS)
    x1 = xLoc + 1.5 - 0.5
    x2 = xLoc + numpyArray.shape[1] - 0.0 + 0.5
    y1 = yLoc + 1.0 - 0.5
    y2 = yLoc + numpyArray.shape[0] - 0.5 + 0.5
    if xCentered:
        x1 = x1 - numpyArray.shape[1]/2.0
        x2 = x2 - numpyArray.shape[1]/2.0
    if yCentered:
        y1 = y1 - numpyArray.shape[0]/2.0
        y2 = y2 - numpyArray.shape[0]/2.0
    gl.glTexCoord2f( 0 , 0 )
    gl.glVertex2f( x1 , y1 )
    gl.glTexCoord2f( 1 , 0 )
    gl.glVertex2f( x2 , y1 )
    gl.glTexCoord2f( 1 , 1)
    gl.glVertex2f( x2 , y2 )
    gl.glTexCoord2f( 0 , 1 )
    gl.glVertex2f( x1, y2 )
    gl.glEnd()
    gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
    gl.glDeleteTextures([ID])
    del ID
    gl.glDisable(gl.GL_TEXTURE_2D)
    return None

# this is a little loop we're using to get our "frame rate" right; if this is made to work, I'm good from here
i = 0
j = 0
start = time.time()
while time.time()-start<10:
    time.sleep(.01) #pretend to do 5ms of other work per frame
    gl.glClearColor(0,0,0,1)
    gl.glClear(gl.GL_COLOR_BUFFER_BIT)
    blitNumpy(imgs[i],0,0,xCentered=False,yCentered=False)
    sdl2.SDL_GL_SwapWindow(stimDisplay.window)
    i+= 1
    if i == len(imgs):
        i=0
    j += 1

print j/(time.time()-start) # we just happen to need this metric
class Experiment(ExpLib.Exp):
    first_run = True  # 
    # bunch of methods that don't interact with either PyGame or SDL2—science stuff

    def trial(self, trial_factors, trial_num):
        if self.first_run:
            pygame.quit()
            self.first_run = False

        time.sleep(0.1)  # maybe unnecessary; just giving PyGame a chance to be fully shut down

        # this next call wraps the script above; the only difference is that 
        # blitNumpy becomes self.blitNumpy, and our FPS loop
        self.sdl_trial()  

        # the experiment's code will go here if I can get this to fly