gpt4 book ai didi

c - GLX 垂直同步事件

转载 作者:太空宇宙 更新时间:2023-11-04 03:30:39 26 4
gpt4 key购买 nike

我想知道是否可以通过任何文件描述符和 [select |投票 | epoll]它。

通常,如果我是对的,glXSwapBuffers() 不会阻止进程,所以我可以做类似的事情:

int init() {
create epollfd;
add Xconnection number to it;
add some other fd like socket timer tty etc...
possibly add a vsync fd like dri/card0 or fb0 or other???
return epollfd;
}

main() {
int run = 1;
int epollfd = init();

while(run) {
epoll_wait(epollfd, ...) {

if(trigedfd = socket) {
do network computing;
}

if(trigedfd = timer) {
do physics computing;
}

if(trigedfd = tty) {
do electronic communications;
}

if(trigedfd = Xconnection number) {
switch(Xevent) {
case key event:
do key computing;
case mouse event:
do mouse computing;
case vsync???:
do GL computings;
glXSwapBuffers();
}
}

if(trigedfd = dri/card0 or fb0 or other???) {
do GL computings;
glXSwapBuffers();
}
}
}

这样我就可以触发任何事件,而不管 vsync 事件何时发生,同时避免在我仅使用 X 绘图功能和可能的 GL 进行 vsync 的情况下产生撕裂效果。

libdrm 可以帮助我吗?更一般的问题是:

那么我必须使用什么 fd 来捕获 vsync 事件,以及如何确保这个 fd 发生的事件是 vsync 事件?

最佳答案

看起来您可以使用 libdrm API 查看 vsync 事件。参见 this blog entry ,特别是 this example code .代码中的注释解释了它是如何工作的:

/* (...)
* The DRM_MODE_PAGE_FLIP_EVENT flag tells drmModePageFlip() to send us a
* page-flip event on the DRM-fd when the page-flip happened. The last argument
* is a data-pointer that is returned with this event.
* (...)
*/

您需要设置一个页面翻转事件处理程序,以便在发生垂直同步时得到通知,该处理程序将由 drmHandleEvent 方法(来自 libdrm)调用,您可以在有事件时调用该方法drm 文件描述符。

然而,将所有这些映射到 X 客户端可能会很困难或不可能。 可能您可以自己打开 drm 设备并只监听 vsync 事件(无需尝试设置模式等),但这也可能被证明是不可能的。相关代码:

drmEventContext ev;
memset(&ev, 0, sizeof(ev));
ev.version = DRM_EVENT_CONTEXT_VERSION;
ev.page_flip_handler = modeset_page_flip_event;

// When file descriptor input is available:
drmHandleEvent(fd, &ev);
// If above works, "modeset_page_flip_event" will be called on vertical refresh.

问题是翻页事件似乎只有在您实际发出翻页(缓冲区交换)请求时才会生成。大概是 X 服务器发出了这样的请求,但它甚至没有必要标记它希望在 vsync 实际发生时得到通知(即使用 DRM_MODE_PAGE_FLIP_EVENT 标记)。

打开正确的 dri 设备也很困难(/dev/dri/card0/dev/dri/card1 或...?)

考虑到以上所有问题的难度/不可靠性/普遍不可行,最简单的解决方案可能是:

  1. 使用单独的线程等待使用标准 GL 调用的垂直同步。根据this page on the OpenGL wiki您应该使用 glXSwapIntervalEXT(1) 来启用垂直同步,然后使用 glXSwapBuffersglFinish 来确保垂直回扫确实发生。
  2. 然后,通知主线程发生了垂直回溯。您可以通过将数据发送到管道或在 Linux 上使用 eventfd 来执行此操作。

更新:

您可以使用 GLX_INTEL_swap_event extension :

Accepted by the parameter of glXSelectEvent and returned in the parameter of glXGetSelectedEvent:

GLX_BUFFER_SWAP_COMPLETE_INTEL_MASK 0x04000000

Returned in the <event_type> field of a "swap complete" event:

GLX_EXCHANGE_COMPLETE_INTEL 0x8180
GLX_COPY_COMPLETE_INTEL 0x8181
GLX_FLIP_COMPLETE_INTEL 0x8182

...

A client can ask to receive swap complete GLX events on a window.When an event is received, the caller can determine what kind of swap occurred by checking the event_type field.

这意味着,如果支持扩展,您可以通过常规 X 事件接收交换通知(如果启用垂直同步,则对应于垂直回溯),您将在 X 连接文件描述符上看到这些通知。

关于c - GLX 垂直同步事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36888288/

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