查看: 3690|回复: 9

请教OSG多线程的问题

[复制链接]

该用户从未签到

发表于 2008-11-27 17:08:07 | 显示全部楼层 |阅读模式
大家好
   在array的《最长的一帧》第28课中提到“单线程和CullDrawThreadPerContext模型不会出现渲染过程与用户更新过程交叠的情形”以及“我们可以允许在上一帧的绘制没有结束之前,就开始下一帧的用户数据更新工作”。以我的理解:在CullDrawThreadPerContext模型下,存在一个调用frame()的线程,以及一个GraphicsThread线程。前一个线程应当执行的是用户更新过程,后一个线程执行cull、draw任务。当地一帧的cull/draw没有完成,而第二帧的APP已经完成时,接下来会不会立即执行cull/draw?由于互斥的原因应当不会立即执行吧,如果不执行是不是可以开始第三帧的APP了?应当也不行吧,那是怎么控制的呢?
请高手指教 thanks in advance.

|_ _APP_ _ |_ _CULL/Draw_ _|
                     |_ _APP_ _|_ _CULL/Draw_ _|

forest

该用户从未签到

发表于 2008-11-27 17:38:30 | 显示全部楼层
二十七日的课程比较详细地介绍了CullDrawThreadPerContext的机制。不会开始执行下一帧的APP工作的,因为主进程已经被_endRenderingDispatchBarrier阻塞住了。
CullDrawThreadPerContext因此也不会出现您的图中的情形,它不是这种机制。这种模式下,下一帧的APP必须在上一帧的DRAW结束后才会开始,和单线程模式类似,不过对多个图形设备的并行计算做了优化处理。

该用户从未签到

 楼主| 发表于 2008-11-28 11:18:31 | 显示全部楼层
谢谢array的耐心解答。
请问在DrawThreadPerContext模式下,由于numThreadsOnStartBarrier = 1;
numThreadsOnEndBarrier = 1;栅栏是不是就不起作用了啊,那样的话主线程与绘制线程似乎独立运行了啊,
会不会出现下面的情况呢
|_ _APP_ _ |_ _CULL/Draw_ _|
                     |_ _APP_ _|_ _CULL/Draw_ _|
或者出现下面的情况
|_ _APP_ _ |_ _CULL/Draw_ _|
                     |_ _APP_ _|             |_ _CULL/Draw_ _|

该用户从未签到

发表于 2008-11-28 11:53:48 | 显示全部楼层
是的,渲染线程确实是独立出来的,这就是多线程渲染效率高的主要原因——这也是目前技术层次看来,能够实现实时渲染的最佳方式。新一帧的APP会在上一帧的渲染结束之前启动,因此需要小心数据变度(setDataVariance)的问题,也就是您的第二幅图的情形。
第一幅图的情形不会出现,因为有swapReadyBarrier来控制各个GraphicsContext线程的同步

该用户从未签到

 楼主| 发表于 2008-11-28 12:05:22 | 显示全部楼层
“由于DrawThreadPerContext模式不存在渲染启动和结束栅栏,因此主进程执行完场景的筛选之后就可以继续执行,进而开始新一帧的用户数据更新工作。而此时GC线程的绘制工作很有可能还没有完成,如果此时场景中某些需要绘制的数据有了改变,将会造成无法预料的事情发生,最严重的当然就是系统崩溃了。

幸好我们还有动态对象阻塞器_endDynamicDrawBlock这个保护伞。在使用这一线程模式以及后面马上要介绍的CullThreadPerCameraDrawThreadPerContext模式时,不要忘记为场景中的变度对象设置setDataVariance(Object:: DYNAMIC)。”
应当把《最长的一帧》看完再问问题的,呵呵
好像您的27课中有一段让人误解的地方

该用户从未签到

发表于 2008-11-28 12:50:11 | 显示全部楼层
我在相应的帖子里给您回复了,看图和代码为主吧~~

该用户从未签到

 楼主| 发表于 2008-11-28 15:01:42 | 显示全部楼层
以下是我对DrawThreadPerContext模式的朦胧理解,请大家指教
1.advance();   eventTraversal();    updateTraversal();这些函数都是在APP阶段完成的吧
2.在DrawThreadPerContext模式下绘制Draw分为前后两个阶段DynamicDraw (DD)和 StaticDraw(SD)
3.在DrawThreadPerContext模式下APP,CULL都是由执行frame()函数的线程完成的(设此线程为AT,执行绘制的线程为GT)
4.
AT:|_ _APP_ _|_ _CULL_ _|
GT:                                       |_ _DD_ _ |_ _SD_ _|
AT:                                                        |_ _APP_ _|_ _CULL_ _|
GT:                                                                                             |_ _DD_ _ |_ _SD_ _|

[ 本帖最后由 forest37 于 2008-11-28 15:04 编辑 ]

该用户从未签到

发表于 2008-11-28 17:39:56 | 显示全部楼层
1、是的
2、的确可以这样说,但是不能称之为前后。绘制时不会对DYNAMIC或STATIC对象进行分类,而是根据DYNAMIC对象的总数设置一处Barrier栅栏,只有所有的DYNAMIC对象绘制完成后才能冲开这处栅栏并继续执行
3、是的,我也如是理解。
4、没有明确的DD/SD分类,除此之外图还是基本准确的

该用户从未签到

 楼主| 发表于 2008-11-29 01:34:47 | 显示全部楼层
那个图好像很不对哦,没有考虑双缓存视图啊,不知道怎么画了,呜呜

该用户从未签到

发表于 2008-11-29 09:18:38 | 显示全部楼层
原帖由 forest37 于 2008-11-29 01:34 发表
那个图好像很不对哦,没有考虑双缓存视图啊,不知道怎么画了,呜呜


没有必要把什么都考虑进来,概念上正确就可以了。实现是另一回事。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表