问题标签 [vsync]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
2103 浏览

c++ - SFML 垂直同步始终开启?

我一直在玩游戏循环和物理。前几天,我添加了一些调试语句来查看我的游戏循环的每一帧花费了多少时间。正如预期的那样,结果在 16 毫秒范围内。但是,我尝试禁用 vsync,这些结果并没有改变。显然 vsync 仍在发生。我注释掉了 SFML 显示调用,果然帧加速了。

好的,那为什么 vsync 会卡住呢?起初我认为这一定是 DSFML(D 语言的 SFML 绑定)中的一个错误。我用C++创建了一个直接使用SFML的简单测试用例,性能特征完全一样!

我的系统如下:

$ inxi -SMG
系统:主机:c7内核:3.16.4-1-ARCH x86_64(64 位)桌面:i3 4.8 发行版:Arch Linux 机器:系统:Google 产品:Parrot v:1.0
Mobo:N/A 型号:N /A BIOS:coreboot v:4.0-4744-gac16405-dirty 日期:10/23/2013
显卡:卡:英特尔第二代核心处理器系列集成显卡控制器
显示服务器:X.Org 1.16.1 驱动程序:英特尔分辨率:1366x768@ 60.02hz
GLX 渲染器:Mesa DRI Intel Sandybridge Mobile GLX 版本:3.0 Mesa 10.3.1

下面给出了 SFML vsync 测试用例,打开了 vsync:

谷歌搜索这个问题,结果表明图形驱动程序正在强制 vsync 开启。但后来我想知道为什么 vsync 适用于我系统上的其他程序?

我写了另一个测试用例,这次使用 SDL2:

现在我禁用 vsync 是这个测试用例,并看到 0ms 范围内的帧时间,正如预期的那样!因此,SFML 实现 vsync 的方式在我的系统上存在问题,而 SDL 似乎可以正确处理它。

导致这种不同行为的两个库之间的实现有什么区别,可以解决吗?我将如何使用 SFML 获得正确的行为?

0 投票
1 回答
395 浏览

directx - DirectX VSYNC inaccuracy

I'm trying to achieve steady fixed 60fps in my D3D app and to do that by doing vsync. I've setup loop like this:

I would expect to see "ms" variable to be always the same, but it's actually varying from around 16.1 ms to something over 17. Is there some wrong assumption I'm making or just plain coding error? Thanks for help in advance.

0 投票
1 回答
927 浏览

android - 在 systrace 中获取 BufferQueue 状态

我试图更好地了解我的应用程序如何与 Android 的缓冲系统交互。具体来说,我想在将帧添加到 SurfaceFlinger 的 BufferQueue 时针对 Vsync 信号进行优化。

我了解在使用 SurfaceViews 时,BufferQueue 信息包含在其中:

如果我使用的是 TextureView 怎么办?在这些情况下没有 SurfaceView 计数器。不使用 SurfaceView 时是否还有其他缓冲区状态指标?应用程序计数器是否也表示 BufferQueue 状态?

BufferQueueProducer.cpp 和 BufferQueueConsumer.cpp 中的以下行似乎暗示了这一点,但如果可能的话,我可以使用信任投票:

0 投票
1 回答
10745 浏览

android - Understanding necessity of Android VSYNC signals

I'm trying to get a better understanding of the Android display subsystem, but one item that's still confusing to me is how VSYNC signals are handled, and why so many exist in the first place.

Android is designed to use VSYNC at its core, but there are multiple VSYNC signals that it employs. Via https://source.android.com/devices/graphics/implement.html in the "VSYNC Offset" section, there is a flow diagram which diagrams three VSYNC signals: HW_VSYNC_0, VSYNC, and SF-VSYNC. I understand that HW_VSYNC is used to update the timing in DispSync, and that VSYNC and SF-VSYNC are used by the apps and surfaceflinger, but why are these individual signals necessary at all? Furthermore, how do the offsets impact these signals? Is there a timing diagram available anywhere which better explains this?

Thanks for any help you can offer.

0 投票
2 回答
274 浏览

opengl - 如何在游戏循环中计算直到最后一刻

作为优化我的 3D 游戏/模拟引擎的一部分,我正在尝试使引擎进行自我优化。

基本上,我的计划是这样的。首先,让引擎测量每帧的 CPU 周期数。然后测量各种子系统消耗的 CPU 周期数(最小值、平均值、最大值)。

鉴于此信息,仅在帧循环中的几个特定点,引擎可以估计有多少“额外 CPU 周期”可用于执行现在可以有效执行的“可选处理”(相关数据现在在缓存中),但如果当前帧有运行不足 CPU 周期的危险,则可能会延迟到某个后续帧。

我们的想法是在繁重的工作上尽可能领先于游戏,因此每个可能的 CPU 周期都可用于处理“要求苛刻的帧”(如“单帧期间的许多碰撞”),而不会调用 glXSwapBuffers( ) 及时在 vsync 的最新可能时刻之前交换后/前缓冲区)。


上述分析假定交换后/前缓冲区是确保恒定帧速率的基本要求。我见过声称这不是唯一的方法,但我不明白其中的逻辑。

我在 glXSwapBuffers() 之前和之后捕获了 64 位 CPU 时钟周期时间,发现帧相差大约 2,000,000 个时钟周期!这似乎是由于 glXSwapBuffers()直到 vsync(当它可以交换缓冲区时)阻塞,而是立即返回。

然后我在 glXSwapBuffers() 之前添加了 glFinish(),这将变化减少到大约 100,000 个 CPU 时钟周期......但随后 glFinish() 被阻塞了 100,000 到 900,000 个 CPU 时钟周期(大概取决于多少工作 nvidia 驱动程序必须在交换缓冲区之前完成)。由于 glXSwapBuffers() 完成处理和交换缓冲区可能需要多长时间的这种变化,我想知道是否有任何“智能方法”有希望。


最重要的是,我不确定如何实现我的目标,这似乎相当简单,并且似乎并没有对底层子系统(例如 OpenGL 驱动程序)提出太多要求。但是,即使在 glXSwapBuffers() 之前使用 glFinish(),我仍然看到“帧时间”有大约 1,600,000 个周期变化。我可以平均测量的“每帧 CPU 时钟周期”速率,并假设平均值产生实际帧速率,但是由于变化如此之大,我的计算实际上可能会导致我的引擎通过错误地假设它可能取决于这些值而跳过帧。

对于所涉及的各种 GLX/OpenGL 函数的细节,或者在实践中可能比我尝试的更好的一般方法,我将不胜感激。

PS:当核心减速或加速时,我的 CPU 的 CPU 时钟频率不会改变。因此,这不是我问题的根源。

0 投票
1 回答
1273 浏览

performance - 分析 OpenGL 应用程序 - 当驱动程序阻塞 CPU 端时

我制作了一个游戏内图形分析器(CPU 和 GPU),Nvidia 驱动程序有一个奇怪的行为,我不确定如何处理。

这是正常情况下的截图: GPU Profiler, vysnc 开启 您可以在这里看到连续 3 帧,GPU 在顶部,CPU 在底部。两个图是同步的。

“END FRAME”栏仅包含对 的调用SwapBuffers。在 GPU 完成所有工作之前它一直处于阻塞状态似乎很奇怪,但这就是驱动程序有时在 vsync 开启时选择做的事情,并且所有工作(CPU 和 GPU)都可以在 16 毫秒内完成(AMD 也是如此)。我的猜测是它这样做是为了最大限度地减少输入滞后。

现在我的问题是它并不总是这样做。根据帧中发生的情况,图表有时看起来像这样: GPU Profiler, vysnc on, V2 这里实际发生的是,第一个 OpenGL 调用是阻塞的,而不是对SwapBuffers. 在这种特殊情况下,阻塞调用是glBufferData. 如果我添加一个可以做到这一点的虚拟代码(创建一个统一缓冲区,用随机值加载它并销毁它),它会更加明显:

GPU Profiler, vysnc on, V2 with dummy code

这是一个问题,因为这意味着图表中的条形可能会无缘无故变得非常大。看到这一点的人可能会得出关于某些代码运行缓慢的错误结论。

所以我的问题是,我该如何处理这种情况?我需要一种始终显示有意义的 CPU 计时的方法。

添加一个加载统一缓冲区的虚拟代码不是很优雅,并且可能不适用于未来版本的驱动程序(如果驱动程序只阻塞绘图调用怎么办?)。

与 a 同步glClientWaitSync看起来也不是一件好事,因为如果帧速率下降,驱动程序将停止阻塞以允许 CPU 和 GPU 帧并行运行,我需要检测到停止调用glClientWaitSync(但我'不知道该怎么做。)

(欢迎提出更好的标题建议。)

编辑:当 GPU 成为瓶颈时,这是没有 vsync 时会发生的情况: GPU Profiler, vysnc 关闭, V2 GPU 帧比 CPU 帧花费的时间更长,因此驱动程序决定在glBufferDataGPU 赶上之前阻塞 CPU。

条件不一样,但问题是:CPU时序是“错误的”,因为驱动程序做了一些OpenGL功能块。这实际上可能是一个比打开 vsync 的例子更容易理解的例子。

0 投票
0 回答
268 浏览

c# - 如何确定显示器刚刚刷新屏幕的时间?

我想将我的 Direct3D9 应用程序中的渲染与监视器的刷新率同步。我想避免使用 VSync,因为它会锁定处理,直到渲染每一帧,从而降低帧速率。最终,我想每秒仅“呈现”一帧 60 次,并在每次调用“呈现”之间处理帧数据。

有没有办法“挂钩”显示器?

0 投票
0 回答
177 浏览

ubuntu - 使用 SDL2 和 vsync 切换窗口焦点时的 Ubuntu 14.04 延迟

我正在学习 SDL2 的基础知识,当我运行我的程序(vsync,窗口化)时,在窗口之间切换焦点和拖动窗口时会有延迟。这适用于所有窗口,而不仅仅是 SDL2 应用程序。未启用 vsync 时,所有窗口都按预期流畅运行。

我正在运行 ubuntu 14.04,使用 nvidia 卡,驱动程序版本 349.12。下面是在我的机器上重现该行为的最小工作示例。

在第二台机器(14.04,bumblebee 驱动程序)上运行此代码会产生平滑的窗口行为,无论是否使用 vsync。我还尝试了许多有和没有 vsync 的游戏,唯一能重现这种行为的是 FTL(我相信这是一款 SDL 游戏)。

如何进一步修复/调试?

0 投票
2 回答
860 浏览

frame-rate - 为什么 Direct2D 在拔下笔记本电脑的外部电源后只能以 30 FPS 运行?

我是 Direct2D 的新手,最近我发现了一个奇怪的问题。插入外部电源后,我的程序以 60 的稳定 FPS 运行,我知道这可能是 VSync 的结果;但是在拔掉外部电源一段时间后,我的程序下降到稳定的 FPS 30(我输出了每两次渲染之间的时间间隔,它显示为 32ms)。

即使我再次插上电源,它仍然保持在 30 FPS,直到我重新启动计算机。

是不是因为我的笔记本电脑在电池供电时关闭了某些东西,导致 FPS 减半?如果是真的,我能做些什么呢?

我的笔记本电脑的操作系统是 Windows 8.1。

以下是一些可能有用的代码。

主循环如下所示:

我敢肯定它需要很少的时间Update(),它可以以 60 的稳定帧速率运行,所以在OnRender().

谢谢!

0 投票
1 回答
665 浏览

opengl - 在 OpenGL 中使用带有 GLFW 的两个视口时卡在 30 fps

使用 glfwSwapInterval(1) 或 glfwSwapInterval(0) 打开和关闭 vsync

单个视口是 glClear --> glViewport(0, 0, win_w,win_h) --> drawscene() --> 渲染循环中的 glfwSwapBuffers

双视口是 glClear --> glViewport(0, 0, win_w/2,win_h) --> drawscene() --> glViewport(win_w/2, 0, win_w/2,win_h) --> drawscene() -- >glfwSwapBuffers 在渲染循环中

我的场景单视口没有 vsync --> 140 fps

我的场景双视口没有 vsync --> 70 fps(正如预期的那样,因为它两次绘制相同的场景)

我的场景单视口具有 vsync --> 60 fps(正如预期的那样,因为我的显示器刷新率为 60Hz)

我的场景双视口带有 vsync --> 30 fps(???我在这里期待 60 fps,因为它在没有 vsync 的情况下实现了 70 > 60 fps,我需要调用任何额外的 GLFW 函数吗?)