gpt4 book ai didi

c - 如何高效绘制framebuffer内容?

转载 作者:IT王子 更新时间:2023-10-29 00:15:10 31 4
gpt4 key购买 nike

我需要为没有连接真实显示器的虚拟 GPU 设备显示基于 RAM 的帧缓冲区。我所拥有的是 DRM_IOCTL_MODE_MAP_DUMB 之后的 RGB32 格式的 mmap 内存块。目前我正在使用通过 XShmCreatePixmap() 创建的 MIT-SHM 共享像素图,如下所示:

shminfo.shmid = shmget(IPC_PRIVATE, bytes, IPC_CREAT|0777);
shminfo.readOnly = False;
shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
shmctl(shminfo.shmid, IPC_RMID, 0);
XShmAttach(dpy, &shminfo);
XShmCreatePixmap(dpy, window, shminfo.shmaddr, &shminfo, width, height, 24);

然后简单地

while (1) {
struct timespec ts = {0, 999999999L / 30};

nanosleep(&ts, NULL);

memcpy(shminfo.shmaddr, mem, bytes);
XCopyArea(dpy, pixmap, window, gc, 0, 0, width, height, 0, 0);
XFlush(dpy);
}

所以它每秒循环 30 次,在 XCopyArea 之后执行 memcpy。问题是它使用了大量的 CPU:在功能强大的机器上为 50%。有没有更好的办法?我能想到两个可能的改进:

  1. 摆脱 memcpy 并仅将 mmap 的内存传递给 MIT-SHM,但看起来 MIT-SHM API 不支持此操作。

  2. 获取某种“内容已更改”通知以摆脱愚蠢的 sleep (但我还没有找到任何合适的东西)。

有什么想法吗?

更新:瓶颈是“memcpy”,如果删除 CPU 使用率变得可以忽略不计。问题似乎是没有办法共享以前 mmap 的内存(如果我正确理解 API)所以我每次都被迫复制整个缓冲区。我也尝试过 glDrawPixels() 和 SDL surfaces,它们似乎都比 MIT-SHM 还要慢。

更新:事实证明 MIT-SHM 不太适合这样的任务。它的主要目的是创建缓冲区并写入(渲染)它而无需 X IPC 的开销。我不需要写任何东西,只需将现有缓冲区“转发”到 X。在这种情况下,共享像素图、共享图像和常规 X 图像 (XCreateImage) 之间没有性能差异。

结论:到目前为止,我还没有找到允许渲染现有缓冲区而无需每次都复制数据的 API。

最佳答案

对于 X11,使用 XShmCreateImage,写入 XImage.data 并使用 XShmPutImage 确保传递 False 使其可见> 为 send_event 参数。您可能还想禁用当前 GC 的暴露事件;设置 PointerMotionHintMask 也有帮助。

SDL1 完成了上述大部分工作,但如果用户和显示格式之间存在不匹配,则会使用阴影表面,并且可能会执行意外的颜色转换。 SDL2 尝试使用硬件加速并可能执行意外的缩放和/或过滤。确保您得到了您所要求的,以避免隐藏操作。

对于这个 30fps 的 blit,%50 的 cpu 使用率听起来很多,为了以防万一,我会重写 sleep 函数如下。

do
errno = 0;
while ( nanosleep(&ts, &ts) && errno == EINTR );

关于c - 如何高效绘制framebuffer内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23873175/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com