你怎么知道你显示的内容是完全绘制在屏幕上的?

Posted

技术标签:

【中文标题】你怎么知道你显示的内容是完全绘制在屏幕上的?【英文标题】:How do you know what you've displayed is completely drawn on screen? 【发布时间】:2013-11-04 16:50:46 【问题描述】:

在计算机显示器上显示图像涉及到图形 API 的使用,该 API 调度一系列异步调用...并在某个给定时间将所需内容放在计算机屏幕上。

但是,如果您想知道在所需图像被完全绘制(并且对用户可见)时的准确 CPU 时间怎么办?

我真的需要在显示所有内容时获取 CPU 时间戳,以便将该时间点与我进行的其他测量相关联。

在不考虑图形堆栈的异步行为的情况下,很多事情都可以得到图形调用时的抖动长度:

多线程; 同步到 V-BLANK(不幸的是,需要避免一些撕裂); 我还忘记了什么? :P

我针对 Linux 上的解决方案,但我对任何其他操作系统持开放态度。我已经研究了 X.org 服务器和 OpenGL API 的 xvideo extension 的部分内容,但我还没有找到有效的解决方案。

我只希望解决方案不涉及入侵视频驱动程序/硬件!

注意:我将无法在所需的硬件上使用最新的 Nvidia G-SYNC。虽然,这项技术会消除一些不可预知的抖动,但我认为它并不能完全解决这个问题。


OpenGL Wiki 建议如下:“如果需要 GPUCPU 同步,则应在缓冲区交换后使用高精度/多媒体计时器而不是 glFinish。”

有人知道在 GPU 队列中的 swapBuffer 调用完成后如何正确获取如此高精度/多媒体计时器值吗?

【问题讨论】:

您忘记了 GPU 是现代操作系统中的虚拟化资源。 Microsoft Windows 在 WDDM(Windows Vista+ 的显示驱动程序模型)中有一个非常复杂的调度程序,您的应用程序可以被具有更高 GPU 优先级的东西(例如桌面窗口管理器)抢占。如果您真正编写的软件具有实时(传统的延迟/截止日期意义而不是高帧率,因为这个术语通常被简化为意味着)GPU 要求,那么这将成为您的障碍:-\ 是的,这就是我偏爱 Linux 用于这个应用程序的原因。虚拟化仍然可能是一个问题,但至少它不是一个黑匣子。为了尽量减少这个问题,我禁用了桌面堆肥扩展(ATI 的 Composite 和 AIGLX)以避免间接渲染。 【参考方案1】:

最近的 OpenGL 提供了同步/栅栏对象。您可以将同步对象放在 OpenGL 命令流中,然后等待它们通过。见http://www.opengl.org/wiki/Sync_Object

【讨论】:

感谢您的回答。尽管与 glFinish 调用一样,目前可用于栅栏的唯一选项是在阻塞操作中等待它们。不幸的是,在 swapBuffer 调用之后放置栅栏会阻塞渲染循环,从而放弃双缓冲的任何优势。 @Jonathan:实际上,OpenGL 调用只会在管道停止且满时阻塞。只有在 后台缓冲区 上的操作达到同步点时,才会发生停顿,在缓冲区交换发生之前。这里的关键词是“后台缓冲区”,您可以完美地继续将内容渲染到要交换的表面以外的帧缓冲区,例如 FBO 渲染缓冲区或纹理附件。

以上是关于你怎么知道你显示的内容是完全绘制在屏幕上的?的主要内容,如果未能解决你的问题,请参考以下文章

leap motion怎么对应屏幕上的位置

Android 上的 openGl es 在右上角显示一个 Square

python如何绘制一个三维空间下的平面?

理解UIView的绘制

试图制作一个绘制像素的着色器

关于Android UI绘制优化你应该了解的知识点