显示从其他 PC 捕获的屏幕缓冲区的最快方法
Fastest way to display a screen buffer captured from other PC
我的问题如下:
我有一个存储 framebuffer 的指针,它会被某个线程不断更改。
我想通过 OpenGL API 显示这个 framebuffer。我的微不足道的选择是每次都使用 glTexImage2D 并一次又一次地加载 framebuffer。这种在帧缓冲区上的加载是必要的,因为帧缓冲区是由 OpenGL API 外部更改的。我认为可能有一些方法或技巧可以加快速度,例如:
通过找出framebuffer内部的变化(有可能吗?)
一些快速重新加载图像的方法
OpenGL可以直接使用framebuffer的指针吗? (因此更少的帧缓冲区复制)
我不确定上述方法是否有效。希望大家多多指教
- By finding out the changes inside the framebuffer (Is it even possible?)
这会减少所需的带宽,因为它是有效的视频压缩。然而,CPU 负载明显更高,而且比仅通过 DMA 复制数据要慢得多。
Some method for fast re-loading of image
使用glTexSubImage2D代替glTexImage2D(注意…Sub…)。 glTexImage2D 每次调用时都要进行完整的纹理初始化,这是相当昂贵的。
如果您的程序使用 OpenGL 执行其他操作 而不仅仅是显示图像,您可以通过减少程序等待事情完成的时间来进一步加快速度使用像素缓冲区对象。基本要点是
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID);
void *pbuf = glMapBuffer();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
thread image_load_thread = start_thread_copy_image_to_pbo(image, pbuf);
do_other_things_with_opengl();
join_thread(image_load_thread();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID);
glUnmapBuffer();
glBindTexture(…);
glTexSubImage2D(…, NULL); /* will read from PBO */
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
draw_textured_quad();
除了创建和加入线程之外,您还可以使用线程池和条件变量来进行线程间同步。
- OpenGL could directly using the pointer of the framebuffer? (So less framebuffer copying)
几乎总是需要复制东西。不用担心副本,如果有必要的话。我上面概述的像素缓冲区对象可能会或可能不会与系统 RAM 中的着色器副本一起工作。本质上,您可以将 glBufferMap 放入进程的地址 space 并直接解码到给定的缓冲区中。但这并不能保证避免进一步复制。
我的问题如下:
我有一个存储 framebuffer 的指针,它会被某个线程不断更改。
我想通过 OpenGL API 显示这个 framebuffer。我的微不足道的选择是每次都使用 glTexImage2D 并一次又一次地加载 framebuffer。这种在帧缓冲区上的加载是必要的,因为帧缓冲区是由 OpenGL API 外部更改的。我认为可能有一些方法或技巧可以加快速度,例如:
通过找出framebuffer内部的变化(有可能吗?)
一些快速重新加载图像的方法
OpenGL可以直接使用framebuffer的指针吗? (因此更少的帧缓冲区复制)
我不确定上述方法是否有效。希望大家多多指教
- By finding out the changes inside the framebuffer (Is it even possible?)
这会减少所需的带宽,因为它是有效的视频压缩。然而,CPU 负载明显更高,而且比仅通过 DMA 复制数据要慢得多。
Some method for fast re-loading of image
使用glTexSubImage2D代替glTexImage2D(注意…Sub…)。 glTexImage2D 每次调用时都要进行完整的纹理初始化,这是相当昂贵的。
如果您的程序使用 OpenGL 执行其他操作 而不仅仅是显示图像,您可以通过减少程序等待事情完成的时间来进一步加快速度使用像素缓冲区对象。基本要点是
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID);
void *pbuf = glMapBuffer();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
thread image_load_thread = start_thread_copy_image_to_pbo(image, pbuf);
do_other_things_with_opengl();
join_thread(image_load_thread();
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboID);
glUnmapBuffer();
glBindTexture(…);
glTexSubImage2D(…, NULL); /* will read from PBO */
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
draw_textured_quad();
除了创建和加入线程之外,您还可以使用线程池和条件变量来进行线程间同步。
- OpenGL could directly using the pointer of the framebuffer? (So less framebuffer copying)
几乎总是需要复制东西。不用担心副本,如果有必要的话。我上面概述的像素缓冲区对象可能会或可能不会与系统 RAM 中的着色器副本一起工作。本质上,您可以将 glBufferMap 放入进程的地址 space 并直接解码到给定的缓冲区中。但这并不能保证避免进一步复制。