我在OpenGL ES中创建了一个运行循环,CADisplayLink以60fps的速度调用了该循环。 AFAIK CADisplayLink称其为后台线程的目标。
我有大约100个状态变量,这些变量由运行循环使用。
问题:在主线程中,我想更改在运行循环中用于绘制内容的状态变量。仅在将所有状态变量设置为其目标值之后,才可以绘制框架。
恐怕在某个时候,当我更改状态变量时,还没有全部更改(在主线程的同一运行循环迭代中的一种大方法中),例如几何形状的位置,存在多个与线程相关的崩溃或问题,CADisplayLink将在我的方法的中间插入,该方法将更新状态变量,然后绘制垃圾或崩溃。
显然,当我仅使用同步或原子属性时,它仍然没有事务性,因此无济于事。我想我需要交易。
我的幼稚方法是这样的:
由运行循环读取的实例变量:
BOOL updatingState;
如果updateState读取为YES,则运行循环方法将跳过绘图。
然后在开始更改状态之前,将其设置为"is"。当所有内容都更改后,我将其设置回NO。
现在,当然是问题了:如果-在我对此进行更改时-运行循环方法正在读取值怎么办?
游戏引擎如何处理此问题?它们具有哪种锁定机制,以便可以在绘制下一帧之前完成状态变量的更改?
最佳答案
您可能会发现读-复制-更新策略很有用。一种可能的实现方式是,每个对象实际上包含渲染参数的两个副本,并且使用原子标记来告知渲染线程使用哪个。您将需要在渲染器中使用读取内存屏障来确保在读取任何参数之前已读取该标志,并在更新程序线程中使用写入存储器屏障来确保在翻转该标志之前写入了所有参数更新。
关于iphone - 游戏引擎中执行安全状态更改的策略是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10638809/