VrApi头文件注释翻译

来源:互联网 发布:js向object中添加元素 编辑:程序博客网 时间:2024/05/30 05:41

VrApi接口说明

         本文翻译自Oculusmobile sdk中的VrApi.h头文件中的注释。该文件中的信息有助于初步了解Oculus mobile sdk工作的流程和原理。

         多个处于同一地址空间的Androidactivities可以协同调用VrApi接口。但是,在同一时间,只能有一个Activity是处在“VR mode”状态下的。接下来将详细说明一个Activity在说明情况下会进入或退出VR模式。

         一个Activity只有在它处于苏醒状态(resume)下,才能进入VR模式。下面显示了VR模式是怎么嵌入到Activity的生命周期的。

         1.  ovr_Initialize()

         2.  VrActivity::onCreate()

         3.  VrActivity::onStart() <--------+

         4.  VrActivity::onResume() <----+  |

         5.  ovr_EnterVrMode()           | |

         6.  ovr_LeaveVrMode()           | |

         7.  VrActivity::onPause() ------+  |

         8.  VrActivity::onStop() ----------+

         9.  VrActivity::onDestroy()

         10.ovr_Shutdown()

         一个Activity要想进入VR模式,它就必须有一个有效的surface。下面显示了VR模式是怎么嵌入到surface的生命周期。

         1.  ovr_Initialize()

         2.  VrActivity::surfaceCreated() <-----+

         3.  VrActivity::surfaceChanged()       |

         4.  ovr_EnterVrMode()                  |

         5.  ovr_LeaveVrMode()                  |

         6.  VrActivity::surfaceDestroyed() ----+

         7.  ovr_Shutdown()

         值的注意的是,surface的生命周期跟activity的生命周期是没必要紧密对应的。这两个生命周期是以一种复制的方式交叉在一起的。一般来说,surfaceCreated()是在onResume()之后调用,surfaceDestroyed()是在onDestroy()之前调用。但是,这不是必然的,例如surfaceDestroyed()也可能是在onDestroy()之后调用。

         surfaceCreated()的调用总是紧跟着surfaceChanged(),onPause()总是在surfaceDestroyed()之前调用。所以说,activity只会在surfaceChanged()或者onResume()(最后调用的那个)和onPause()之间才能够同时处于苏醒状态及有有效的surface。也就是说,App将在这种情况下进入VR模式,离开VR模式在onPause()调用之后。

         这套API被设计用于有一个简单是SurfaceView的Activity。这个Activity的生命周期及Surface的生命周期完全由native层控制。在Nativecode中发送生命周期事件给native code。这套API不能工作在GLSurfaceView上。GLSurfaceView管理着window surface和EGLSurface。GLSurfaceView可能会在调用onPause()之前解绑EGLSurface。这样的话,就没办法在EGLSurface销毁之前退出VR模式。另外一个问题是GLSurfaceView用接口eglChooseConfig()创建EGLContext。如果用户设置了前置4x MSAA的话,eglChooseConfig()会使用多重采样的标志作为参数。用一个多重采样的前置缓冲对于时间扭曲渲染来说是纯粹的浪费。一个NativeActivity可以被用来自动处理生命周期的事件。但是,EGLConfig应该手动选择,这样才能保证前置缓冲不会是多重采样的。

 

目视图像合成

         ovr_WarpSwap()通过参数ovrTimeWarpParms::MinimumVsyncs控制着合成速率。ovr_WarpSwap()还控制着在图像刷新周期的某个点合成开始。ovr_WarpSwap()只会在之前的目视图像已经被异步时间扭曲线程填充好后返回,同时要保证至少经过了MinimumVsyncs。异步时间扭曲线程经过一个刷新周期填充新的目视图像到一半,同时可以开始更新第一个眼睛的图像。所以说,ovr_WarpSwap()在一个刷新周期内返回一半,之后合成就开始了。

         在ovr_WarpSwap()返回之后,合成有一个整个刷新周期的时间去生成新的目视图像直到下一个半点。在下一个半点中,时间扭曲有半个刷新周期去更新第一个眼睛的图像。时间扭曲线程接下来会等待V-Sync(垂直同步刷新),然后利用另外半个刷新周期去更新第二个眼睛图像。异步时间扭曲用一个高性能GPU context去侵蚀合成的周期。所以合成器不配在一个完整的刷新周期内一直占有GPU。不过异步时间扭曲通常是很快速的,把大部分GPU时间遗留给了合成器。

         为了在贴图GPU上有好的表现,CPU产生命令和GPU执行将会重叠。因为GPU会等到所有的渲染命令都被提交后才开始渲染一帧图像。由于CPU生成命令和GPU执行是重叠的,传感器采样和图像开始显示之间的时间间隔为2.5个显示刷新周期(当MinimumVsyncs ==1).多管线渲染引擎将有一个较大的延迟,在传感器采样和图像开始绘制之间。通过使用最新的视图绑定,传感器采样跟图像开始绘制之间的时间可以减少到1.5个刷新周期。

         相对于最新的传感器采样数据,合成器使用在目视图像绘制时间中间时间点处的预测传感器输入数据。预测的时间点采样ovr_GetPredictedDisplayTime()来计算。向前预测的帧数取决于管线的深度及目视图像渲染经过的最小的刷新周期。在每个目视图像显示之前,时间小于半个刷新周期,异步时间扭曲会用最新的传感器数据获取新的传感器预测输入。然后异步时间扭曲会根据新的传感器输入校正目视图像。也就是说,异步时间扭曲总是会校正目视图像即使预测的传感器输入不是完美的。不过,预测的越精准,异步时间扭曲引入更少的黑色在边缘。

         理想情况下,目视图像只会显示在目视图像预测时间中央的刷新周期中。也就是说,一组目视图像从预测时间减去半个最小同步刷新周期开始显示。目视图像不应该在这个时间点之前显示因为这会带来内部画面颤动。理想来说,目视图像同样不应该在预测时间加上半个最小同步刷新周期之后继续显示。但是当合成器没有按时生成目视图像时这可能发生。

MinimumVsyncs = 1

|---|---|---|---|---|---|---|---|---|  - V-syncs

| * | * | * | * | * | * | * | * | * |  - eye image display periods (* = predictedtime)

 

MinimumVsyncs = 2

|---|---|---|---|---|---|---|---|---|  - V-syncs

|  *   |   *  |   *   |  *   |   *  -eye image display periods (* = predicted time)

 

MinimumVsyncs = 3

|---|---|---|---|---|---|---|---|---|  - V-syncs

|    *     |     *    |     *     |  -eye image display periods (* = predicted time)

0 0
原创粉丝点击