Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ OSX以最小延迟将像素推送到屏幕_C++_Macos_Opengl_Draw_Low Latency - Fatal编程技术网

C++ OSX以最小延迟将像素推送到屏幕

C++ OSX以最小延迟将像素推送到屏幕,c++,macos,opengl,draw,low-latency,C++,Macos,Opengl,Draw,Low Latency,我正在尝试开发一些延迟非常低的图形应用程序,但我对通过OpenGL绘制到屏幕所需的时间感到非常失望。我在网上找到的每一个关于它的讨论都涉及到优化OpenGL管道,但都没有得到我需要的结果 看看这个: 你可能注意到了这一点:使用C++ OpenGL应用程序,在屏幕上拖动鼠标,在OpenGL中绘制鼠标位置,OpenGL落后3或4帧。显然,OSX可以以很低的延迟将[光标]绘制到屏幕上,但OpenGL要慢得多。假设我不需要做任何漂亮的OpenGL渲染。我只是想把像素推到屏幕上。有没有一种方法可以让我完

我正在尝试开发一些延迟非常低的图形应用程序,但我对通过OpenGL绘制到屏幕所需的时间感到非常失望。我在网上找到的每一个关于它的讨论都涉及到优化OpenGL管道,但都没有得到我需要的结果

看看这个:


你可能注意到了这一点:使用C++ OpenGL应用程序,在屏幕上拖动鼠标,在OpenGL中绘制鼠标位置,OpenGL落后3或4帧。显然,OSX可以以很低的延迟将[光标]绘制到屏幕上,但OpenGL要慢得多。假设我不需要做任何漂亮的OpenGL渲染。我只是想把像素推到屏幕上。有没有一种方法可以让我完全绕过OpenGL,更快地绘制屏幕?或者这种功能会被锁定在内核中某个我无法访问的地方吗?

这里有很多延迟

  • 输入事件→ 绘图状态延迟
在典型的交互式应用程序中,通常会出现一个事件循环

  • 收集用户输入
  • 处理用户输入
  • 决定要画什么
  • 拉到后缓冲区
  • 调回前缓冲区
  • 使用编写事件–更新–显示循环的常用方法,在上一次迭代的步骤5和下一次迭代的步骤1之间几乎没有延迟。这意味着步骤2、3和4使用的数据落后于大约一个帧周期

    所以这是延迟的第一个来源

    • 三重缓冲/合成延迟
    许多图形管线支持三重缓冲,以实现更平滑的显示更新。除了前后两个缓冲区外,中间还有第三个缓冲区。绘制这些缓冲区的平均速率是显示刷新周期。缓冲区本身正好在显示刷新周期进行步进。因此,这又增加了一个帧延迟周期

    如果您在一个带有窗口合成器(MacOS X默认设置)的系统上运行,这将有效地添加另一个缓冲区阶段,因此如果您有双缓冲区模式,它将提供三重缓冲区,如果您有三重缓冲区,它将提供“四重”缓冲区(此处引用,因为四重缓冲区是通常用于立体渲染的术语)


    对此,您可以做些什么:

    • 关闭合成功能
    通过DWMAPI和MacOS X的Windows允许关闭合成或绕过合成器

    • 减少输入滞后

    尽可能晚地收集和集成用户输入(使用高分辨率睡眠)。如果你只有一个非常简单的场景,你可以把画推到离V-Sync截止日期很近的地方;事实上,英伟达OpenGL的实现有一个特定于供应商的扩展,允许在下一个V-Syc.

    之前休眠到特定的时间。
    如果您的场景很复杂,但可分为需要低延迟用户输入的部分和不太重要的部分,那么您可以更早地绘制高延迟内容,并且只在最后一刻将用户输入集成到其中。当然,如果使用鼠标来控制观看方向,或者更糟糕的是,在为VR头戴式显示器进行渲染时,事情会变得很困难。

    datenwolf的答案非常好。我只想在关于合成器级别的三重缓冲的讨论中添加一点,因为我非常熟悉Microsoft Windows桌面合成器

    我知道您在这里询问有关OSX的问题,但是我将要讨论的实现细节是实现这些东西的最明智的方式,我希望看到其他系统也以这种方式工作

    您可能在应用程序级别启用的三重缓冲为交换链添加了第三个缓冲区,该缓冲区被同步以刷新。这种三重缓冲的方式确实增加了延迟,因为第三个缓冲区必须被显示,并且在发生这种情况之前,任何东西都不允许触碰它(这是D3D的强制行为——行为和功能本身在OpenGL中没有定义);但是桌面窗口管理器(Windows)的工作方式略有不同

    我见过大多数驱动程序为桌面合成实现的行为是帧丢弃。在刷新之间完成多个帧的任何情况下,除1个帧外,所有这些帧都将被丢弃。实际上,使用窗口而不是全屏+三重缓冲可以降低延迟,因为当第三个缓冲区(由合成器拥有)有一个完成的帧等待显示时,它不会阻止缓冲区交换

    如果帧率不合理地一致,则会产生一系列完全不同的视觉问题。从技术上讲,属于丢弃帧的像素具有无限延迟,因此,如果您需要在屏幕上显示绘制的每一帧,那么通过这种方式减少延迟的好处可能毫无价值

    我相信,通过禁用VSYNC并在窗口中绘图,可以在OSX上实现这种行为(如果您愿意)。在这种情况下,VSYNC基本上只作为帧调整的一种形式(以延迟换取一致性),而不管您以何种速率绘制,合成器本身都会消除撕裂


    关于鼠标光标延迟: 任何现代窗口系统中的光标都将始终以最小延迟跟踪。图形硬件上有一个称为“硬件光标”的功能,其中驱动程序存储光标位置,然后每次刷新一次,让硬件将光标覆盖在帧缓冲区中等待扫描的对象的顶部。因此,即使您的应用程序在60 Hz显示器上以30 FPS的速度绘制,当使用硬件光标时,光标也会每16 ms更新一次

    这完全绕过了所有图形API,但非常有限(例如,它使用OS定义)