Chapter 98 · 离屏渲染与 GPU 管线

EGL 离屏上下文

先检测当前 DLL 的 EGL 能力,再选择独立 EGL 上下文或普通 RenderTarget 回退;不要在主渲染帧内嵌套创建 EGL 上下文。

98

概念

EGL 是 OpenGL ES 的平台接口层。XGE 将 EGL 能力探测、显式 EGL 上下文和普通 RenderTarget 回退分开:先探测当前构建是否包含 PBuffer 或 Surfaceless 支持,再决定是否创建独立上下文。绝大多数窗口应用只需要 RenderTarget;它不需要嵌套 EGL 上下文。

API 速查

函数说明
xgeEGLCapsGet查询当前编译的 EGL、PBuffer、Surfaceless 和 native-window 能力。
xgeEGLInit在应用初始化阶段创建独立 EGL 上下文。
xgeEGLMakeCurrent将已创建的 EGL 上下文绑定到当前线程。
xgeOffscreenInit初始化离屏封装;不应在已有主渲染帧中嵌套调用。

构建并生成可验证截图

gcc -O2 -I. -o build\ch98_main1.exe examples\tutorial_capture\ch98_main1.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
build\ch98_main1.exe --capture tutorial\img\ch98_1.png

示例:先探测,再选择路径

xge_egl_caps_t caps = { 0 };
xgeEGLCapsGet(&caps);
if (caps.bCompiled && caps.bPBuffer) {
    // 在应用初始化阶段创建独立 PBuffer 上下文。
    xge_egl_desc_t desc = { 0 };
    desc.iWidth = 512; desc.iHeight = 512; desc.bPBuffer = 1;
} else {
    // 普通窗口应用使用 xgeRenderTargetCreate 作为跨平台回退。
}

完整代码

权威源码位于 examples/tutorial_capture/ch98_main1.c。它只调用 xgeEGLCapsGet,将 compiled、offscreen、PBuffer、surfaceless 与 native-window 能力显示成状态卡,并显示始终可选的 RenderTarget 回退。这样截图证明的是当前 DLL 的真实能力,而不是在桌面窗口中伪造一个成功的第二上下文。

代码讲解

  • EGLCapsGet:它报告的是当前构建能力,不是“任何桌面窗口都拥有 EGL”。
  • EGLInit:独立上下文应在应用初始化阶段创建,描述中必须提供 PBuffer、Surfaceless 或 native window 之一。
  • RenderTarget 回退:需要离屏纹理而不需要独立 GL 上下文时,优先使用普通 RenderTarget。
  • 线程场景:创建和 MakeCurrent 的线程约束需要由平台后端实际验证;能力探测不保证跨线程成功。

要点与陷阱

  • 禁止嵌套初始化:不要在已有 xgeRun 帧回调中反复调用 xgeOffscreenInit 或 xgeEGLInit。
  • 必须先检查能力:PBuffer 和 Surfaceless 在不同平台/构建中可能不可用;将 XGE_ERROR_UNSUPPORTED 作为正常分支处理。
  • 单线程所有权:同一 EGL 上下文不能同时被两个线程 MakeCurrent。
  • 截图含义:本章截图验证的是能力检测与 RenderTarget 回退的渲染,而非后台线程上传。

进阶练习

  1. 在应用初始化阶段根据 bPBuffer 选择 EGL PBuffer 或 RenderTarget 回退,并记录选择结果。
  2. 在支持 EGL 的 Linux 目标上,为独立上下文添加一条受控的 headless 渲染测试。
XGE EGL 能力状态与 RenderTarget 回退
图:当前构建的 EGL 能力状态与跨平台 RenderTarget 回退;红色状态表示本次 Windows DLL 未编入 EGL。