Files
XCEngine/docs/api/XCEngine/RHI/OpenGL/OpenGLFence/OpenGLFence.md

2.9 KiB
Raw Blame History

OpenGLFence

命名空间: XCEngine::RHI

类型: class

头文件: XCEngine/RHI/OpenGL/OpenGLFence.h

描述: OpenGL 后端的同步对象封装,使用单个 GLsync 和两份 CPU 侧原子计数,近似实现 RHIFence 的 timeline 风格接口。

概览

OpenGL 原生提供的是一次性的 GLsync 栅栏,而不是 D3D12/Vulkan 那种严格单调、可长期复用的 timeline fence。OpenGLFence 的实现思路是:

  • GPU 侧只保留一个当前有效的 GLsync
  • CPU 侧记录“最近一次 signal 的值”
  • 再记录“最近一次确认完成的值”

这样做可以让跨后端 RHI 保持统一的 Signal(value) / Wait(value) / GetCompletedValue() 接口形状,但底层语义仍然是 OpenGL 风格的单栅栏模型。

当前实现的真实行为

  • 同一时间只维护一个 GLsync
  • Initialize 只设置计数值,不创建同步对象
  • Signal 新值时,如果旧 GLsync 还在,会先等待并删除旧栅栏
  • Signal(value) 会先 glFlush(),再插入新的 glFenceSync
  • Wait 成功等待后,会把 m_completedValue 直接写成当前 m_signaledValue
  • GetCompletedValue 只做轮询,不会在查询时清理同步对象
  • GetNativeHandle 是懒创建接口,本身可能新增一段栅栏
  • Signal() 的无参重载并不是“递增 1”而是固定转发为 Signal(1)

设计背景

商业级引擎在 OpenGL 后端里,通常都会做这类“接口现代化,底层实现务实化”的适配。原因很简单:

  • 上层系统希望用统一的 fence API 驱动命令队列、截图、测试和提交流程
  • OpenGL 没有真正的 timeline fence可选方案本来就有限
  • 单个 GLsync 包装器已经足够覆盖当前引擎里最常见的“提交后等待完成”需求

换句话说,当前类的目标不是完美模拟显式 API而是把 OpenGL 的同步原语整理成对引擎友好的形式。

生命周期

重要限制

  • 不是严格意义上的 timeline fence
  • 不保证值单调递增
  • 不保留多段 in-flight 历史,只关注“当前这一个 sync”
  • GetNativeHandle() 有副作用
  • 通过 OpenGLDevice::CreateFence(...) 创建时,initialValue > 0 会被折叠成 1

关键方法

相关文档