• 详细错误
com.jogamp.opengl.GLException: J3D-Renderer-1: createImpl ARB n/a but required, profile > GL2 requested (OpenGL >= 3.1). Requested: GLProfile[GL3bc/GL3bc.hw], current: 3.1 (Compat profile, compat[ES2, ES3], FBO, hardware) - 3.1 Mesa 20.0.8
at jogamp.opengl.x11.glx.X11GLXContext.createImpl(X11GLXContext.java:440)
at jogamp.opengl.GLContextImpl.makeCurrentWithinLock(GLContextImpl.java:765)
at jogamp.opengl.GLContextImpl.makeCurrent(GLContextImpl.java:648)
at jogamp.opengl.GLContextImpl.makeCurrent(GLContextImpl.java:586)
at javax.media.j3d.JoglPipeline.createNewContext(JoglPipeline.java:6411)
at javax.media.j3d.Canvas3D.createNewContext(Canvas3D.java:4612)
at javax.media.j3d.Canvas3D.createNewContext(Canvas3D.java:2386)
at javax.media.j3d.Renderer.doWork(Renderer.java:881)
at javax.media.j3d.J3dThread.run(J3dThread.java:271)

DefaultRenderingErrorListener.errorOccurred:
CONTEXT_CREATION_ERROR: Renderer: Error creating Canvas3D graphics context
graphicsDevice = X11GraphicsDevice[screen=0]
canvas = javax.media.j3d.SwCanvas3D[canvas0,0,0,1433x806]
X11Util.Display: Shutdown (JVM shutdown: true, open (no close attempt): 1/1, reusable (open, marked uncloseable): 0, pending (open in creation order): 1)
X11Util: Open X11 Display Connections: 1
X11Util: Open[0]: NamedX11Display[:0, 0x7f30d73600, refCount 1, unCloseable false]
tsit@tsit-GW-001M1A-FTF:/opt/Taishan/Suite$
  • 解决办法一(对于某些版本的LINUX有效)
  • 分析起因:在新的LINUX上系统上经常闪退

  以前在老的KYLIN/UOS系统上,用方法一确实解决了问题。去年换了新版本之后,这一招也不灵了,直接崩溃闪退。本来如果是功能无效,不闪退,这事也就不了了之(因为在苹果上几乎必然闪退);或者大家都死,也就算了。结果有意思的事情出现了:在KYLIN/UOS上,无锡这边的机器表现正常,泰安那边经常死。推测是显卡不同导致的。于是吾就想:能不能分析一下运行路径,看看能不能解决?起码搞清楚原因。

  • createImpl

  由错误可知,这里是产生异常的地方。自然的,可以从这里找一下分叉。

  初步来看,分支产生于426行,if( 0 != contextHandle ),就是contextHandle产生失败,导致闪退。为什么闪退?那应该是跟本地方法有关。

contextHandle = GLX.glXCreateContext()

  • createContextARB

正确的时候,major=3,minor=1。

  • AbstractGraphicsConfiguration

在虚拟机上,GLProfile[GL2/GL2.hw]

在出错机上,GLProfile[GL3/GL3.hw]

  那么这个是哪里来的?是产生Surface时就有了。吾想继续跟踪下去,看看怎么加载的。后来想这个思路不对,不同机器支持的不一样,不能强制统一。

  • contextHandle=0并不会出错。

    吾试着强制返回0,在虚拟机上并不出错,有一个输出信息大意是:不支持GL3,回落(fall back)到GL2。

  • 闪退原因

  既然contextHandle=0并不会导致问题,那么就是这一句有问题:

if( glp.isGL3() && createContextARBTried )

  结合Config的信息,出错机上这个判断正好为真,进入其中代码,一通操作于是就崩溃了。

  • 解决办法

  解决办法也真的简单,要防止上述语句为真即可。吾定义了一个常量:ENABLE_GL3_TO_GL2。测试后都正常了。

  简单吧?真正的功劳,是伟大的开源。没有他们,什么都是瞎扯。所以吾将修改公开出来(不公开违反开源协议)。