Skip to content

Commit 7153be3

Browse files
committed
freedesktop.glesv2 / glesv1 / opengl:补上渲染链
EGL 能初始化,然后没有 GL 可调 —— 合成器是拿到 context 之后用 GLES2 画的,所以这一条 链之前是断的。这三个包接上它。 ⚠ 本提交同时更新 freedesktop.egl 的 sha256:承载 GL 家族需要重切 libglvnd 的 v1.7.0, 于是 main 上那个描述符的 sha256 再次失效,合并即恢复。次序问题已记在 2026-08-30-gbm-cross-repo-closed-loop-plan.md §19.6。 只做不需要 X11 的三个。libGLX 和 libGL 才是拉 X11 的那两个(dep_x11/dep_xext/ dep_glproto,libGL 经 libGLX 间接依赖),建它们会把 Xorg 塞进每个消费者的依赖图, 包括根本没有显示器的 headless GBM 项目。这三个不碰窗口系统,而且正好是合成器要用的。 与 payload 逐符号核对过: libGLESv2 358 个 GL 入口 == payload 的 358,逐个符号一致 libOpenGL 1044 == payload 的 1044,逐个符号一致 libGLESv1_CM 145 -- payload 根本不带这个库,是新增能力 测试成员做的是 V3「真能画」,不是符号存在性:GBM → EGL → surfaceless context → FBO → glClear → glReadPixels,读回 64 128 191 255,与清的颜色分毫不差。 GL_VERSION 报 OpenGL ES 3.2 Mesa 25.0.7。 三个坑写进了注释: * GBM 平台没有 pbuffer config,headless 要走 EGL_KHR_surfaceless_context + FBO; * libGLdispatch 导出全量 GL 面(包括 glMatrixMode),所以「dlsym 找不到某名字」 永远不成立,断言必须基于 dladdr 的归属; * 三个 GL flavour 符号面重叠(都导出 glClear),同一进程链两个会让名字绑到先加载 的那个 —— 实测:一个想用 GLESv2 的程序里 glClear 落到了 libGLESv1_CM.so.1, 毫无提示。所以测试成员只依赖一个 flavour,并断言 glClear 确实解析在它里面。
1 parent 2f19d4a commit 7153be3

7 files changed

Lines changed: 523 additions & 1 deletion

File tree

‎mcpp.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ members = [
8686
"tests/examples/expat",
8787
"tests/examples/wayland",
8888
"tests/examples/egl",
89+
"tests/examples/gl",
8990
"tests/examples/libgbm",
9091
"tests/examples/libpng",
9192
"tests/examples/libwebp",

‎pkgs/f/freedesktop.egl.lua‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ package = {
128128
GLOBAL = "https://github.com/mcpplibs/libglvnd/archive/refs/tags/v1.7.0.tar.gz",
129129
CN = "https://gitcode.com/mcpp-res/libglvnd/releases/download/1.7.0/libglvnd-1.7.0.tar.gz",
130130
},
131-
sha256 = "d50579071c5e0b883cddae82fac3f8d7c575b6523c9ea64b855a3d6f50951d47",
131+
sha256 = "11347b0ffffbcb9ca51cd3941dff9ef923b21bb1e9469f3e5cff42ed487bf77d",
132132
},
133133
},
134134
},

‎pkgs/f/freedesktop.glesv1.lua‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
-- freedesktop.glesv1 — libGLESv1_CM.so.1, plus `import khronos.glesv1;`.
2+
--
3+
-- OpenGL ES 1.x (common profile) dispatched through GLVND. This is the half that was missing: with
4+
-- `freedesktop.egl` a project could reach `eglInitialize` and then had no GL
5+
-- to call. A Wayland compositor takes its context through EGL and draws with
6+
-- GLES2, so without this the render chain stopped one step short.
7+
--
8+
-- ─────────────────────────────────────────────────────────────────────────
9+
-- SHAPE: a source build, out of the same fork as freedesktop.egl
10+
--
11+
-- Same criterion, same fork, same reasoning as that package: libglvnd is a
12+
-- separable project, so it is built rather than bound. `libGLdispatch.so.0`
13+
-- comes from a sibling workspace member by PATH — being the ONE dispatch point
14+
-- in a process is what GLVND exists for, and every GL entry point in this
15+
-- library routes through it, so the two must be one build.
16+
--
17+
-- The ecosystem payload `xim:libglvnd` ships the same soname, and binding it
18+
-- instead would work by soname reuse — measured. It is still a source build,
19+
-- because a payload library carries a DT_NEEDED on `libGLdispatch.so.0` and
20+
-- would then be dispatching through a DIFFERENT build of GLVND than the one
21+
-- this index provides, with only `__glDispatchGetABIVersion` between that and
22+
-- a runtime failure.
23+
--
24+
-- For this library the payload is not even an option: `xim:libglvnd` ships
25+
-- libEGL, libGLdispatch, libGLESv2, libGL, libGLX and libOpenGL — and no
26+
-- libGLESv1_CM. This package is new capability, not a re-packaging.
27+
--
28+
-- ─────────────────────────────────────────────────────────────────────────
29+
-- THE MODULE IS NAMED FOR THE SPECIFICATION
30+
--
31+
-- `khronos.glesv1`, not `freedesktop.glesv1`, and the package/module mismatch is
32+
-- deliberate: freedesktop hosts libglvnd, but OpenGL ES 1.x (common profile) is a **Khronos**
33+
-- specification with several implementations. A module name is global and
34+
-- permanent in a way a package name is not, so it names the INTERFACE's owner.
35+
-- Same rule as `khronos.egl`; `mcpplibs.openkal` paid for it (its 0.1.0 was
36+
-- withdrawn for putting the imported module under the implementation's
37+
-- control).
38+
--
39+
-- THE EXPORT LIST IS THE HEADER INTERSECTED WITH THE LIBRARY, generated by the
40+
-- fork's `mcpp/tools/genglmod.sh` and diffed by its CI. A header can declare
41+
-- more than its library dispatches, so exporting the header wholesale would
42+
-- put names in the module that do not link.
43+
--
44+
-- The `GL_*` CONSTANTS are macros and no module can export a macro: include
45+
-- the same header beside the import when you need `GL_COLOR_BUFFER_BIT`.
46+
package = {
47+
spec = "1",
48+
namespace = "freedesktop",
49+
name = "glesv1",
50+
description = "libGLESv1_CM.so.1 — OpenGL ES 1.x (common profile) through GLVND, built from source, with a C++23 module",
51+
licenses = {"MIT"},
52+
repo = "https://github.com/mcpplibs/libglvnd",
53+
type = "package",
54+
55+
xpm = {
56+
linux = {
57+
-- libglvnd's version, as with freedesktop.egl: what a consumer
58+
-- pins is which libglvnd it links, not which GL spec level.
59+
["1.7.0"] = {
60+
url = {
61+
GLOBAL = "https://github.com/mcpplibs/libglvnd/archive/refs/tags/v1.7.0.tar.gz",
62+
CN = "https://gitcode.com/mcpp-res/libglvnd/releases/download/1.7.0/libglvnd-1.7.0.tar.gz",
63+
},
64+
sha256 = "11347b0ffffbcb9ca51cd3941dff9ef923b21bb1e9469f3e5cff42ed487bf77d",
65+
},
66+
},
67+
},
68+
69+
mcpp = "*/mcpp/glesv1/mcpp.toml",
70+
}

‎pkgs/f/freedesktop.glesv2.lua‎

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
-- freedesktop.glesv2 — libGLESv2.so.2, plus `import khronos.glesv2;`.
2+
--
3+
-- OpenGL ES 2.0/3.x dispatched through GLVND. This is the half that was missing: with
4+
-- `freedesktop.egl` a project could reach `eglInitialize` and then had no GL
5+
-- to call. A Wayland compositor takes its context through EGL and draws with
6+
-- GLES2, so without this the render chain stopped one step short.
7+
--
8+
-- ─────────────────────────────────────────────────────────────────────────
9+
-- SHAPE: a source build, out of the same fork as freedesktop.egl
10+
--
11+
-- Same criterion, same fork, same reasoning as that package: libglvnd is a
12+
-- separable project, so it is built rather than bound. `libGLdispatch.so.0`
13+
-- comes from a sibling workspace member by PATH — being the ONE dispatch point
14+
-- in a process is what GLVND exists for, and every GL entry point in this
15+
-- library routes through it, so the two must be one build.
16+
--
17+
-- The ecosystem payload `xim:libglvnd` ships the same soname, and binding it
18+
-- instead would work by soname reuse — measured. It is still a source build,
19+
-- because a payload library carries a DT_NEEDED on `libGLdispatch.so.0` and
20+
-- would then be dispatching through a DIFFERENT build of GLVND than the one
21+
-- this index provides, with only `__glDispatchGetABIVersion` between that and
22+
-- a runtime failure.
23+
--
24+
-- ─────────────────────────────────────────────────────────────────────────
25+
-- THE MODULE IS NAMED FOR THE SPECIFICATION
26+
--
27+
-- `khronos.glesv2`, not `freedesktop.glesv2`, and the package/module mismatch is
28+
-- deliberate: freedesktop hosts libglvnd, but OpenGL ES 2.0/3.x is a **Khronos**
29+
-- specification with several implementations. A module name is global and
30+
-- permanent in a way a package name is not, so it names the INTERFACE's owner.
31+
-- Same rule as `khronos.egl`; `mcpplibs.openkal` paid for it (its 0.1.0 was
32+
-- withdrawn for putting the imported module under the implementation's
33+
-- control).
34+
--
35+
-- THE EXPORT LIST IS THE HEADER INTERSECTED WITH THE LIBRARY, generated by the
36+
-- fork's `mcpp/tools/genglmod.sh` and diffed by its CI. A header can declare
37+
-- more than its library dispatches, so exporting the header wholesale would
38+
-- put names in the module that do not link.
39+
--
40+
-- The `GL_*` CONSTANTS are macros and no module can export a macro: include
41+
-- the same header beside the import when you need `GL_COLOR_BUFFER_BIT`.
42+
package = {
43+
spec = "1",
44+
namespace = "freedesktop",
45+
name = "glesv2",
46+
description = "libGLESv2.so.2 — OpenGL ES 2.0/3.x through GLVND, built from source, with a C++23 module",
47+
licenses = {"MIT"},
48+
repo = "https://github.com/mcpplibs/libglvnd",
49+
type = "package",
50+
51+
xpm = {
52+
linux = {
53+
-- libglvnd's version, as with freedesktop.egl: what a consumer
54+
-- pins is which libglvnd it links, not which GL spec level.
55+
["1.7.0"] = {
56+
url = {
57+
GLOBAL = "https://github.com/mcpplibs/libglvnd/archive/refs/tags/v1.7.0.tar.gz",
58+
CN = "https://gitcode.com/mcpp-res/libglvnd/releases/download/1.7.0/libglvnd-1.7.0.tar.gz",
59+
},
60+
sha256 = "11347b0ffffbcb9ca51cd3941dff9ef923b21bb1e9469f3e5cff42ed487bf77d",
61+
},
62+
},
63+
},
64+
65+
mcpp = "*/mcpp/glesv2/mcpp.toml",
66+
}

‎pkgs/f/freedesktop.opengl.lua‎

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
-- freedesktop.opengl — libOpenGL.so.0, plus `import khronos.opengl;`.
2+
--
3+
-- version-neutral OpenGL dispatched through GLVND. This is the half that was missing: with
4+
-- `freedesktop.egl` a project could reach `eglInitialize` and then had no GL
5+
-- to call. A Wayland compositor takes its context through EGL and draws with
6+
-- GLES2, so without this the render chain stopped one step short.
7+
--
8+
-- ─────────────────────────────────────────────────────────────────────────
9+
-- SHAPE: a source build, out of the same fork as freedesktop.egl
10+
--
11+
-- Same criterion, same fork, same reasoning as that package: libglvnd is a
12+
-- separable project, so it is built rather than bound. `libGLdispatch.so.0`
13+
-- comes from a sibling workspace member by PATH — being the ONE dispatch point
14+
-- in a process is what GLVND exists for, and every GL entry point in this
15+
-- library routes through it, so the two must be one build.
16+
--
17+
-- The ecosystem payload `xim:libglvnd` ships the same soname, and binding it
18+
-- instead would work by soname reuse — measured. It is still a source build,
19+
-- because a payload library carries a DT_NEEDED on `libGLdispatch.so.0` and
20+
-- would then be dispatching through a DIFFERENT build of GLVND than the one
21+
-- this index provides, with only `__glDispatchGetABIVersion` between that and
22+
-- a runtime failure.
23+
--
24+
-- NOT to be confused with `compat.opengl`, which ships the Khronos GL
25+
-- HEADERS from the OpenGL-Registry and no library. This one is the library.
26+
--
27+
-- ─────────────────────────────────────────────────────────────────────────
28+
-- THE MODULE IS NAMED FOR THE SPECIFICATION
29+
--
30+
-- `khronos.opengl`, not `freedesktop.opengl`, and the package/module mismatch is
31+
-- deliberate: freedesktop hosts libglvnd, but version-neutral OpenGL is a **Khronos**
32+
-- specification with several implementations. A module name is global and
33+
-- permanent in a way a package name is not, so it names the INTERFACE's owner.
34+
-- Same rule as `khronos.egl`; `mcpplibs.openkal` paid for it (its 0.1.0 was
35+
-- withdrawn for putting the imported module under the implementation's
36+
-- control).
37+
--
38+
-- THE EXPORT LIST IS THE HEADER INTERSECTED WITH THE LIBRARY, generated by the
39+
-- fork's `mcpp/tools/genglmod.sh` and diffed by its CI. A header can declare
40+
-- more than its library dispatches, so exporting the header wholesale would
41+
-- put names in the module that do not link.
42+
--
43+
-- The `GL_*` CONSTANTS are macros and no module can export a macro: include
44+
-- the same header beside the import when you need `GL_COLOR_BUFFER_BIT`.
45+
package = {
46+
spec = "1",
47+
namespace = "freedesktop",
48+
name = "opengl",
49+
description = "libOpenGL.so.0 — version-neutral OpenGL through GLVND, built from source, with a C++23 module",
50+
licenses = {"MIT"},
51+
repo = "https://github.com/mcpplibs/libglvnd",
52+
type = "package",
53+
54+
xpm = {
55+
linux = {
56+
-- libglvnd's version, as with freedesktop.egl: what a consumer
57+
-- pins is which libglvnd it links, not which GL spec level.
58+
["1.7.0"] = {
59+
url = {
60+
GLOBAL = "https://github.com/mcpplibs/libglvnd/archive/refs/tags/v1.7.0.tar.gz",
61+
CN = "https://gitcode.com/mcpp-res/libglvnd/releases/download/1.7.0/libglvnd-1.7.0.tar.gz",
62+
},
63+
sha256 = "11347b0ffffbcb9ca51cd3941dff9ef923b21bb1e9469f3e5cff42ed487bf77d",
64+
},
65+
},
66+
},
67+
68+
mcpp = "*/mcpp/opengl/mcpp.toml",
69+
}

‎tests/examples/gl/mcpp.toml‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# GL test project — the render half of the graphics stack.
2+
#
3+
# THIS MEMBER DECLARES ITS OWN [indices], and has to. The workspace root maps
4+
# `compat` to this checkout, and an index is looked up BY NAMESPACE, so
5+
# `freedesktop.*` would resolve against the published index rather than the
6+
# packages under test. A member-level table REPLACES the root's.
7+
[indices]
8+
freedesktop = { path = "../../.." }
9+
10+
[package]
11+
name = "gl-tests"
12+
version = "0.1.0"
13+
standard = "c++23"
14+
15+
# EGL plus ONE GL flavour, which is the only correct shape — and this member
16+
# used to name all three, which is how the reason was found.
17+
#
18+
# libGLESv2, libGLESv1_CM and libOpenGL are three FRONT ENDS onto the same
19+
# libGLdispatch, and their symbol sets overlap: `glClear` is exported by all
20+
# three. Link two of them and the name binds to whichever the loader mapped
21+
# first — measured here, `glClear` resolved to libGLESv1_CM.so.1 in a program
22+
# that meant GLESv2, silently and with nothing to warn about it. That is the
23+
# same class of ambiguity soname reuse creates, and it is avoided the same way:
24+
# pick one.
25+
#
26+
# A project picks the flavour it writes against. A Wayland compositor is GLESv2
27+
# (it takes a context through EGL and draws with shaders), so that is what this
28+
# member is. libGLESv1_CM and libOpenGL have their own tests in the fork, where
29+
# each is the only GL library in the process.
30+
[target.'cfg(linux)'.dependencies.freedesktop]
31+
egl = "1.7.0"
32+
glesv2 = "1.7.0"
33+
34+
# GBM is how a headless test gets a real context without a display server.
35+
[target.'cfg(linux)'.dependencies.compat]
36+
libgbm = "25.0.7"

0 commit comments

Comments
 (0)