Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] use GL_PIXEL_PACK_BUFFER for video rendering to accelerate readback #21

Open
ChickenPige0n opened this issue Mar 26, 2025 · 2 comments
Labels
enhancement New feature or request

Comments

@ChickenPige0n
Copy link

Is your feature request related to a problem? Please describe.
渲染器的较低速度大概来自于读取gpu数据的耗时,通过pbo可以显著降低编码器等待下一帧数据的时间

Describe the solution you'd like
GL_PIXEL_PACK_BUFFER 是 OpenGL 中的一种缓冲区对象类型,属于 Pixel Buffer Object (PBO) 的一种,主要用于高效地处理像素数据的读取(Download)操作。它的核心作用是优化从 GPU(如帧缓冲区或纹理)向 CPU 传输数据的过程,避免同步等待,提升性能。


关键点解析

  1. 基本功能

    • 当绑定为 GL_PIXEL_PACK_BUFFER 时,该缓冲区用于存储通过 glReadPixels()glGetTexImage() 等函数从 GPU 读取的像素数据(如屏幕截图、纹理内容)。
    • 传统方式(无PBO)下,这些操作会直接返回数据到CPU内存,可能因管线阻塞导致性能下降。而PBO允许异步传输,数据先暂存到GPU端的缓冲区,后续再映射到CPU。
  2. 性能优势

    • 异步操作:GPU可以先将数据写入PBO,而CPU无需等待,后续通过 glMapBuffer() 映射访问。
    • DMA传输:利用显卡的直接内存访问(DMA)机制,减少CPU干预,提升吞吐量。
    • 避免暂存内存:省去了传统方式中可能的额外内存拷贝。
  3. 对立类型

    • GL_PIXEL_UNPACK_BUFFER:用途相反,用于将数据从CPU上传到GPU(如纹理更新)。

典型使用流程

// 1. 创建并绑定PBO
GLuint pbo;
glGenBuffers(1, &pbo);
glBindBuffer(GL_PIXEL_PACK_BUFFER, pbo);

// 2. 分配缓冲区大小(不初始化数据)
glBufferData(GL_PIXEL_PACK_BUFFER, width * height * 4, NULL, GL_STREAM_READ);

// 3. 从帧缓冲区读取数据到PBO(非阻塞)
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0);

// 4. 后续需要时,映射PBO到CPU内存
GLubyte* pixels = (GLubyte*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
if (pixels) {
    // 处理数据...
    glUnmapBuffer(GL_PIXEL_PACK_BUFFER); // 解除映射
}

// 5. 清理
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glDeleteBuffers(1, &pbo);

适用场景

  • 高性能截图/录像:避免实时读取帧缓冲区的延迟。
  • GPU计算结果的回读:如深度学习推理后从显存获取数据。
  • 纹理分析:读取纹理内容进行后期处理或保存。

注意事项

  • 同步问题:映射缓冲区前需确保GPU操作完成(可通过 glFenceSync 或查询对象)。
  • 缓冲区大小:需匹配数据格式(如RGBA每像素4字节)。
  • 驱动兼容性:PBO需要OpenGL 2.1+或ARB/EXT扩展支持。

通过合理使用 GL_PIXEL_PACK_BUFFER,可以显著减少CPU-GPU间的数据传输瓶颈,尤其在大数据量或实时应用中效果显著。
Describe alternatives you've considered
None

Additional context
phi-recorder [https://github.com/2278535805/Phi-Recorder/blob/main/src-tauri/src/render.rs#L879]
使用这种方法,使渲染速度达到了约300fps,对编码器的使用率较高。

@ChickenPige0n ChickenPige0n added the enhancement New feature or request label Mar 26, 2025
@ChickenPige0n
Copy link
Author

Seems requires webgl2 to work

@Naptie
Copy link
Member

Naptie commented Mar 26, 2025

该方案可能需要大幅修改 Phaser 的内部实现;以及需要一并提升前后端数据传输速度才能有较为显著的优化效果。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants