如何在Linux

时间:2016-09-02 19:08:44

标签: c++ linux vsync

我需要创建一个C ++函数,它将返回下一个Vsync间隔作为浮点值的秒数。

为什么?

我正在创建显示跟随鼠标光标的矩形的程序。 表面上看,OpenGL在glXSwapBuffers函数中提供了一个vsync机制,但我发现这是不可靠的。有些卡驱动程序可以获得vsync;和别人不一样。在某些情况下,你会获得vsync,但你也会获得额外的2帧延迟。

但这不是OpenGL中的错误。该规范有意模糊:             “然后后台缓冲区的内容变得不确定。             更新通常发生在垂直回扫期间             显示器,             而不是在调用glXSwapBuffers之后立即。“ 关键词是“通常”......基本上glXSwapBuffers不承诺蹲下w.r.t.垂直同步。去图。

在我目前尝试解决这个基本问题时,我目前猜测初始vsync时间,然后后面假设相位等于经过时间MOD 1 /(59.85Hz),这似乎与我当前的监视器同步。但这不能很好地工作,因为我实际上并不知道初始阶段。所以我得到一滴眼泪。至少它不会四处走动。但我真正需要的是以某种方式测量当前的vsync阶段。

不,我不想依赖某些OpenGL调用来为我做一个vsync。由于规范中含糊不清,这使得OpenGL实现可以随意添加延迟。

不,我不想依赖某些SGI扩展或其他必须安装的东西来使其工作。这是图形101. Vsync。只需要一种方法来查询它的状态。一些内置的,始终安装的API必须具有此功能。

也许我可以创建一个以某种方式等待Vsync的辅助线程,并记录发生这种情况的时间?但要注意以下顺序:

#include <sys/ioctl.h>
#include <fcntl.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/fb.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>

int main()
{
  int fb = open("/dev/fb0", O_RDWR);
  assert(fb != -1);
  int zero = 0;
  if (ioctl(fb, FBIO_WAITFORVSYNC, &zero) == -1)
    printf("fb ioctl failed: %s\n", strerror(errno));
}

在Debian中不起作用。结果:

% ./a.out
fb ioctl failed: Inappropriate ioctl for device
% ls -l /dev/fb0
crw-rw-rw- 1 root video 29, 0 Sep  1 20:52 /dev/fb0

必须有某种方法可以从设备或其他设备读取相位 OpenGL调用。 OpenGL是图形的东西。 Vsync是图形101。

请帮忙。

4 个答案:

答案 0 :(得分:1)

当您在Linux内核源代码中搜索FBIO_WAITFORVSYNC时,您可以看到它仅针对少数显卡实现,但并非针对所有显卡实现。

因此,如果您碰巧拥有许多其他卡中的一张,则会出现“不恰当的ioctl for device”,这意味着没有为此显卡驱动程序实现。

也许How to wait for VSYNC in Xlib app?会给你一些正确方向的暗示。

答案 1 :(得分:0)

  

这是图形101. Vsync。只需要一种方法来查询它的状态。一些内置的,始终安装的API必须具有此功能。

不,那里&#34;必须&#34; n不是这样做的方法。至少,没有任何暴露于的东西。当然不是跨平台的任何东西。

毕竟,你不拥有屏幕。系统拥有屏幕;你只租用它的一部分,因此受到系统的支配。系统处理vsync;你的工作是填写那里显示的图像。

考虑一下Vulkan,这个级别与你最近没有实际 图形驱动程序的情况一样低。它的WSI接口明确地设计为避免允许你做&#34;等到下一个vsync&#34;。

它的演示系统确实提供了各种模式,但唯一一个需要支持的实现是FIFO:严格vsync,但没有撕裂。当然,Vulkan的WSI至少可以让你选择你想要多少图像缓冲。但是如果你只使用带有双缓冲区的FIFO,并且你在提供该图像时迟到了,那么在下一次vsync之前你的交换是不可见的。

答案 2 :(得分:0)

优于放弃的解决方案概要:

  1. 在digi-key上搜索输出同步信号的MAX芯片。

  2. 安装RS232卡。

  3. 将同步信号连接到RS232上的握手线。

  4. 使用适用于任何Linux的标准termios API。

  5. 陶瓷环氧树脂块装有惊人产品,售价500美元。

答案 3 :(得分:0)

一个简短的回答是:当视频缓冲很昂贵时,vsync 曾经在计算机上流行。如今,随着双缓冲动画的普遍使用,它变得不那么重要了。在 Windowing 系统之前,我曾经从 IBM-PC 上的显卡访问 vsync,即使现在也不会介意获得 VSYNC。使用双缓冲,您仍然有可能在将缓冲区写入视频内存时发生光栅扫描的风险,因此同步它会很好。但是,通过双缓冲,您将消除直接视频绘制中的许多“闪光”效果和其他伪像,因为您正在执行线性 blt,而不是单个像素操作。

也有可能(如上一张海报所暗示的)您的两个缓冲区都存在于视频内存中,以及显示管理器可以仔细管理屏幕上的 blts(合成)的想法都可以渲染不存在的效果。

我现在该如何处理?我保留了一个帧计时器,例如每秒 30 次,用于翻转缓冲区。它与显卡上的实际帧时间不是特别同步。