@gjsify/webgl 0.47.0 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +59 -0
  2. package/package.json +15 -15
package/README.md CHANGED
@@ -198,6 +198,65 @@ platform, not from the bridge:
198
198
 
199
199
  Remaining darwin gaps are tracked in [`status/open-todos.md`](../../../status/open-todos.md).
200
200
 
201
+ ### The darwin GL 4.1 ceiling
202
+
203
+ The one-line rule in [packages/framework/AGENTS.md](../AGENTS.md) links here for the
204
+ measurement behind it, because a rule without its reason gets "simplified" back into the
205
+ bug. Measured on macOS 15.7 / GdkMacosGLContext (`4.1 APPLE-21.1.1`, GLSL 4.10).
206
+
207
+ **The two missing entry points, reproduced.** `glInvalidateFramebuffer` and
208
+ `glInvalidateSubFramebuffer` are GL 4.3 and absent, hence the `epoxyGlVersion() >= 43` gate
209
+ in `webgl2-rendering-context.vala` — libepoxy ABORTS on a missing entry point rather than
210
+ returning null. They are also the only two, and that is a count anyone can re-take: of the
211
+ 219 `epoxy_gl*` entry points `libgwebgl.dylib` references, `dlsym` against
212
+ `OpenGL.framework` resolves 217.
213
+
214
+ ```bash
215
+ nm -u libgwebgl.dylib | sed -n 's/^ *_epoxy_//p' | grep -E '^gl[A-Z]'
216
+ # then, per name, ctypes.CDLL('/System/Library/Frameworks/OpenGL.framework/OpenGL')
217
+ ```
218
+
219
+ **The GLES 3.0 spellings with no desktop-4.1 equivalent stay missing**, and this is the part
220
+ the shader rewrite above does not reach: `GL_PRIMITIVE_RESTART_FIXED_INDEX` (4.3 on desktop)
221
+ and the mandatory ETC2/EAC compressed formats. Both surface as a **draw-time** error rather
222
+ than a compile failure, so a shader that compiles is not evidence that a scene using them
223
+ will render.
224
+
225
+ For the dialect rewrite itself — including why **win32 is rewritten too**, which this file
226
+ predicted wrongly once — see [Platform coverage](#platform-coverage) above. Host diagnosis:
227
+ `gjsify run packages/framework/webgl/scripts/probe-gl-host.js`, which also draws a
228
+ shader-free pattern so a blank window cannot be mistaken for a failed shader.
229
+
230
+ ## HiDPI: the two canvas bridges are NOT symmetric
231
+
232
+ **This asymmetry is a whole bug class, and it is invisible on every machine you are likely to develop on.**
233
+
234
+ GTK silently pre-scales a `Gtk.DrawingArea`'s Cairo context, so Canvas2D code written in logical pixels renders sharp with nothing to do. `Gtk.GLArea` does **not**: its framebuffer is `allocation x scale-factor` and `gl.viewport` is in raw device pixels.
235
+
236
+ So the GL side reports the DRAWING BUFFER in device pixels (`canvas.width` / `canvas.height`, hence `gl.drawingBufferWidth`) while CSS layout size stays logical (`clientWidth` / `offsetWidth`), and `installGlobals()` publishes `devicePixelRatio` as an ACCESSOR over the widget's live `get_scale_factor()`. The identity
237
+
238
+ ```
239
+ clientWidth * devicePixelRatio === canvas.width
240
+ ```
241
+
242
+ is what lets an unmodified Three.js or Excalibur viewport cover the whole framebuffer.
243
+
244
+ Reporting the allocation as `canvas.width` — as this bridge did until 2026-08 — is invisible at scale-factor 1, which is every desktop, every CI runner and every test VM. On the first scale-factor-3 host it drew each scene into the bottom-left NINTH of its widget: measured on a OnePlus 6T running postmarketOS / GNOME Mobile, where the teapot, the pixel-postprocessing and the Excalibur showcases all rendered a 120x218 corner of a 360x655-logical widget.
245
+
246
+ `@gjsify/dom-elements`' register seeds `devicePixelRatio: 1` as the widget-less default only. A real `Gtk.GLArea` cannot regression-test this, because its host reports 1 — `html-canvas-element.spec.ts` varies the scale factor through a stub, which is the entire point of that stub.
247
+
248
+ ## Naming the GL you actually got
249
+
250
+ `WEBGL_debug_renderer_info` is implemented (the spec'd `VENDOR` / `RENDERER` stay masked) and `bridge.rendererInfo` reads it, so a CPU rasteriser (`isSoftwareRenderer`) costs ONE stderr line. A GPU-less host is otherwise invisible: every draw call succeeds, and only the frame budget tells.
251
+
252
+ **It is DIAGNOSTIC ONLY.** The same driver carries a demand-driven three.js scene and needs 1.1 s for a single textured full-screen draw in a game, so a renderer swap keys on a MEASURED frame budget, never on this string.
253
+
254
+ ## Resize, clone and the WebGL2 overrides
255
+
256
+ - On resize `WebGLBridge` dispatches a DOM `resize` and re-invokes the last rAF callback — demand-driven re-render, no animation loop.
257
+ - A canvas clones PLAIN (`_createCloneTarget`): there is one GLArea and it stays with the original.
258
+ - `WebGL2RenderingContext` overrides `texImage2D`, `texSubImage2D` and `drawElements` from the WebGL1 base, bypassing WebGL1 format/type validation — the native Vala side handles all GLES 3.2 formats.
259
+
201
260
  ## Diagnosing a host
202
261
 
203
262
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/webgl",
3
- "version": "0.47.0",
3
+ "version": "0.49.0",
4
4
  "description": "WebGL module for Gjs",
5
5
  "module": "lib/esm/index.js",
6
6
  "types": "lib/types/index.d.ts",
@@ -61,8 +61,8 @@
61
61
  "WebGL"
62
62
  ],
63
63
  "devDependencies": {
64
- "@gjsify/cli": "^0.47.0",
65
- "@gjsify/unit": "^0.47.0",
64
+ "@gjsify/cli": "^0.49.0",
65
+ "@gjsify/unit": "^0.49.0",
66
66
  "@types/bit-twiddle": "^1.0.3",
67
67
  "@types/node": "^25.9.2",
68
68
  "typescript": "^6.0.3"
@@ -72,10 +72,10 @@
72
72
  "@girs/gjs": "4.6.0",
73
73
  "@girs/gtk-4.0": "4.6.0",
74
74
  "@girs/gwebgl-0.1": "0.1.0-4.0.0-rc.5",
75
- "@gjsify/dom-elements": "^0.47.0",
76
- "@gjsify/dom-events": "^0.47.0",
77
- "@gjsify/event-bridge": "^0.47.0",
78
- "@gjsify/utils": "^0.47.0",
75
+ "@gjsify/dom-elements": "^0.49.0",
76
+ "@gjsify/dom-events": "^0.49.0",
77
+ "@gjsify/event-bridge": "^0.49.0",
78
+ "@gjsify/utils": "^0.49.0",
79
79
  "bit-twiddle": "^1.0.2",
80
80
  "glsl-tokenizer": "^2.1.5"
81
81
  },
@@ -90,13 +90,13 @@
90
90
  },
91
91
  "homepage": "https://github.com/gjsify/gjsify/tree/main/packages/framework/webgl#readme",
92
92
  "optionalDependencies": {
93
- "@gjsify/webgl-darwin-arm64": "0.47.0",
94
- "@gjsify/webgl-darwin-x64": "0.47.0",
95
- "@gjsify/webgl-linux-arm64": "0.47.0",
96
- "@gjsify/webgl-linux-ppc64": "0.47.0",
97
- "@gjsify/webgl-linux-riscv64": "0.47.0",
98
- "@gjsify/webgl-linux-s390x": "0.47.0",
99
- "@gjsify/webgl-linux-x64": "0.47.0",
100
- "@gjsify/webgl-win32-x64": "0.47.0"
93
+ "@gjsify/webgl-darwin-arm64": "0.49.0",
94
+ "@gjsify/webgl-darwin-x64": "0.49.0",
95
+ "@gjsify/webgl-linux-arm64": "0.49.0",
96
+ "@gjsify/webgl-linux-ppc64": "0.49.0",
97
+ "@gjsify/webgl-linux-riscv64": "0.49.0",
98
+ "@gjsify/webgl-linux-s390x": "0.49.0",
99
+ "@gjsify/webgl-linux-x64": "0.49.0",
100
+ "@gjsify/webgl-win32-x64": "0.49.0"
101
101
  }
102
102
  }