我知道它已经被问了好几次没有明确的答案,我已经向 nVIDIA 提交了一个错误。但是,我仍在寻找比在 Prism-D3D 引擎中启动 JavaFX 更好的解决方法(它立即允许通过 nVIDIA 创建后续的 OpenGL 上下文)。
环境:
- nVIDIA 860m,驱动337.88、340.43、340.66(四驱驱动)
- Java 8u11(也测试了 x86/x64 和 Java 7)
测试失败:
- 英伟达简介
- NvOptimusEnablement(用 C 编写的自定义启动器)
- 首先调用 OpenCL(用 C 编写的自定义启动器)
- 首先调用 Cuda(JCuda,它实际上显示 nVIDIA 名称但 OpenGL 不受影响)
失败的 API:
- JavaFX8 ES2 管道(它确实起作用,请参阅https://github.com/AqD/JOGL-FX)
- JOGL 2.1.5
解决方法:
- JavaFX8 D3D 管道。D3D 初始化工作后创建的所有 GLContext。
我将问题归结为一个非常简单的示例,调用realtech-vr OpenGL 扩展查看器(用 .NET 编写)。里面有一个原生的“infogl.dll”,它读取 GL 信息,显然在 oevClientInitialize 之后立即激活 Optimus。
奇怪的是,调用 infogl.dll 的最简单的控制台程序可以工作:
Win32.oevSetDriverVersion("10.18.10.3621", 2176);
Win32.oevClientLoadDatabase(File.ReadAllText("C:\\Program Files (x86)\\realtech VR\\OpenGL Extensions Viewer 4.1\\extensions.xml"));
Win32.oevClientInitialize();
for (var i = 0; i <= 9; i++)
{
var tree = Marshal.PtrToStringAnsi(Win32.oevClientGetCapsAndExtTree(i));
Console.WriteLine(tree.Split('\n').First(ln => ln.Contains("text_id=\"357\"")));
}
Console.ReadLine();
但是 JNA 编写的 Java 代码却没有:
infogl.INSTANCE.oevSetDriverVersion("10.18.10.3621", 2176);
String extXml = null;
try {
extXml = new String(
Files.readAllBytes(Paths.get("C:\\Program Files (x86)\\realtech VR\\OpenGL Extensions Viewer 4.1\\extensions.xml")),
"UTF-8");
} catch (IOException e) {
throw new RuntimeException(e);
}
infogl.INSTANCE.oevClientLoadDatabase(extXml);
infogl.INSTANCE.oevClientInitialize();
for (int i = 0; i <= 9; i++)
{
String tree = infogl.INSTANCE.oevClientGetCapsAndExtTree(i);
System.out.println(Arrays.asList(tree.split("\\n")).first(ln -> ln.contains("text_id=\"357\"")));
}
它与可执行文件名“java”无关——我试过了。
JavaFX D3D 解决方案不合适,因为它在 AMD Radeon 芯片上将 OpenGL FPS 降低了一半——我认为在 nVIDIA 芯片上一定也一样糟糕,这就是为什么我试图让它与 ES2 管道一起工作。