使用OpenCL和SWT直接进行帧缓冲访问

时间:2016-06-03 12:42:08

标签: java swt opencl framebuffer direct-buffer

我编写了一个OpenCL - 内核(JOCL),它占用了几百兆字节的输入数据,并生成了一个视口友好的RGB-Image。此图像应以SWT - GUI显示,刷新率至少为10 fps,以实现实时交互(平移,缩放,伽玛等)。

我想出了一个有效但不太理想的解决方案:

  1. 在Java中创建一个byte[] - 数组作为帧缓冲区(ABGR)
  2. 用CL-buffer
  3. 包装byte[] - 数组
  4. 创建ImageData以包装byte[] - 数组
  5. 将CL缓冲区作为参数
  6. 传递给OpenCL内核
  7. 对于每个帧更新,重复:
    1. 调用OpenCL内核来填充byte[] - 数组
    2. 根据ImageData - 对象
    3. 创建新的Image
    4. 将图片绘制到某些Canvas
    5. Canvas.redraw()
  8. 我不喜欢这个解决方案:

    • 我假设byte[] - 数组将被复制并转换为目标的布局,以便在画布中绘制图像。如果我知道帧缓冲区的内存位置和布局,则可以省略两者。
    • 我相信Canvas'内部帧缓冲区驻留在主机的内存中。所以它毕竟必须被复制回显卡的内存中。
    • 我想使用ByteBuffer.allocateDirect()而不是在JVM的内存中分配byte[] - 数组,但是我不能构建一个基于它的ImageData - 对象作为支持数组是可选的。 (好吧,我可能会使用try-or-fallback-approach。)
    • ImageData每个通道最多接受8位(我没有在文档中明确提到这一点,但是在源代码中)。我想为每个通道生成10位(10:10:10),以便能够处理它们的机器。

    如何减少内存副本和转换次数?

    我不怕在内核中实现几个特定于平台/设备的内存布局。对于一些奇怪的案例和不太常见的平台,我仍然将目前正在进行的实施作为后备。

    我知道有一个GLCanvas可用于更直接访问使用OpenGL的实现(如JOGL),但我不喜欢依赖和捆绑OpenGL与我的想法项目,只是为了加速帧缓冲写入。

    更新:我想我必须使用OpenGL将这些部分粘合在一起:垃圾收集器不时地杀死我的byte[] - 数组,这会导致整个崩溃JVM。另一个副本(直接缓冲区 - > byte[] - 数组)可以解决这个问题,这是不可接受的。

    似乎不可能使GLCanvas的现有实现与OpenCL进行通信,因为它缺少与窗口系统通信的系统。相比之下,OpenGL提供了这样的集成。

0 个答案:

没有答案