簡體   English   中英

如何在 Linux 中查詢 Vsync 相位

[英]How to query Vsync phase in Linux

我需要創建一個 C++ 函數,它將返回到下一個 Vsync 間隔的秒數作為浮點值。

為什么?

我正在創建顯示跟隨鼠標光標的矩形的程序。 表面上,OpenGL 在 glXSwapBuffers 函數中提供了一個 vsync 機制,但我發現這是不可靠的。 使用某些卡驅動程序,您可以獲得 vsync; 與其他人你不。 在某些情況下,您會獲得 vsync,但也會獲得額外的 2 幀延遲。

但這不是 OpenGL 中的錯誤。 規范故意含糊其辭:“后台緩沖區的內容然后變得未定義。更新通常發生在監視器的垂直回溯期間,而不是在調用 glXSwapBuffers 之后立即發生。” 關鍵詞是“通常”......基本上 glXSwapBuffers 不承諾蹲下 wrt 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。

請幫忙。

當您在 Linux 內核源代碼中搜索FBIO_WAITFORVSYNC時,您可以看到,它僅適用於少數顯卡,而不適用於所有顯卡。

因此,如果您碰巧擁有許多其他卡中的一張,則會收到“設備的 ioctl 不合適”,這僅意味着未針對此顯卡驅動程序實現。

也許如何在 Xlib 應用程序中等待 VSYNC? 給你一些正確方向的提示。

一個比放棄更好的解決方案的概述:

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

  2. 安裝 RS232 卡。

  3. 將同步信號連接到 RS232 上的握手線。

  4. 使用適用於任何 Linux 的標准 termios API。

  5. 將驚人的產品裝入陶瓷環氧樹脂塊中,售價 500 美元。

這是圖形 101。Vsync。 只需要一種查詢其狀態的方法。 一些內置的、總是安裝的 API 必須有這個。

不,“必須”沒有辦法做到這一點。 至少,不是任何暴露給你的東西。 當然不是任何跨平台的東西。

畢竟,您不擁有屏幕。 系統擁有屏幕; 您只是租用了其中的一部分,因此受制於系統。 系統處理vsync; 你的工作是填寫顯示在那里的圖像。

考慮一下 Vulkan,它的級別與您現在將要獲得的級別一樣低,而實際上不是圖形驅動程序。 它的 WSI 接口經過明確設計,以避免允許您執行諸如“等到下一次 vsync”之類的操作。

它的演示系統確實提供了多種模式,但唯一需要實現支持的是 FIFO:嚴格的 vsync,但沒有撕裂。 當然,Vulkan 的 WSI 至少允許您選擇所需的圖像緩沖量。 但是,如果您僅將 FIFO 與雙緩沖區一起使用,並且您遲遲沒有提供該圖像,那么您的交換將在下一次 vsync 之前不可見。

一個簡短的回答是:當視頻緩沖很昂貴時,vsync 曾經在計算機上流行。 如今,隨着雙緩沖動畫的普遍使用,它變得不那么重要了。 在使用 Windowing 系統之前,我曾經從 IBM-PC 上的顯卡訪問 vsync,即使現在也不會介意獲得 VSYNC。 使用雙緩沖,您仍然有可能在將緩沖區寫入視頻內存時發生光柵掃描的風險,因此同步它會很好。 但是,通過雙緩沖,您將消除直接視頻繪制中的許多“閃光”效果和其他偽影,因為您正在執行線性 blt 而不是單個像素操作。

也有可能(如前一張海報所暗示的)兩個緩沖區都存在於視頻內存中的事實,以及顯示管理器可以仔細管理屏幕上的 blts(合成)的想法都可以渲染不存在的效果。

我現在如何處理? 我保留了一個幀計時器,例如每秒 30 次,用於翻轉緩沖區。 它與顯卡上的實際幀時間並不特別同步。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM