ntk 7.3.1 → 7.3.3
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.
- package/lib/gl.js +34 -6
- package/lib/renderingcontext_2d.js +15 -6
- package/package.json +1 -1
package/lib/gl.js
CHANGED
|
@@ -32,8 +32,11 @@ import { nodeRequire } from './builtin.js';
|
|
|
32
32
|
* - `GL_NO_DRIVER` — the addon loaded but the GPU libraries it needs are
|
|
33
33
|
* missing (`libgbm`, `libEGL`, `libGLESv2`), or this is not Linux.
|
|
34
34
|
* - `GL_NO_DEVICE` — no readable DRM render node (`/dev/dri/renderD*`).
|
|
35
|
-
* - `GL_REMOTE_DISPLAY` —
|
|
36
|
-
*
|
|
35
|
+
* - `GL_REMOTE_DISPLAY` — a TCP or forwarded display, so there is no local
|
|
36
|
+
* socket to hand the server a buffer down.
|
|
37
|
+
* - `GL_NO_FD_PASSING` — the display is local, but this JavaScript runtime
|
|
38
|
+
* cannot send a descriptor over the socket. Bun is the case in the field;
|
|
39
|
+
* x11 does it through a Node internal Bun does not implement.
|
|
37
40
|
* - `GL_NO_DRI3` — the server has no DRI3/Present (Xvfb, Xephyr, XQuartz).
|
|
38
41
|
* - `GL_IMPORT_FAILED` — the server refused the buffer; usually client and
|
|
39
42
|
* server on different DRM devices.
|
|
@@ -45,6 +48,7 @@ export const GLError = {
|
|
|
45
48
|
NO_DRIVER: 'GL_NO_DRIVER',
|
|
46
49
|
NO_DEVICE: 'GL_NO_DEVICE',
|
|
47
50
|
REMOTE_DISPLAY: 'GL_REMOTE_DISPLAY',
|
|
51
|
+
NO_FD_PASSING: 'GL_NO_FD_PASSING',
|
|
48
52
|
NO_DRI3: 'GL_NO_DRI3',
|
|
49
53
|
IMPORT_FAILED: 'GL_IMPORT_FAILED',
|
|
50
54
|
CONTEXT_FAILED: 'GL_CONTEXT_FAILED'
|
|
@@ -235,6 +239,14 @@ export function canPassDescriptors(display) {
|
|
|
235
239
|
|
|
236
240
|
const displayName = () => globalThis.process?.env?.DISPLAY || 'the X server';
|
|
237
241
|
|
|
242
|
+
/** What is running this, for an error that is about the runtime. */
|
|
243
|
+
const runtimeName = () => {
|
|
244
|
+
const versions = globalThis.process?.versions;
|
|
245
|
+
if (versions?.bun) return `Bun (${versions.bun})`;
|
|
246
|
+
if (versions?.deno) return `Deno (${versions.deno})`;
|
|
247
|
+
return versions?.node ? `Node (${versions.node})` : 'JavaScript runtime';
|
|
248
|
+
};
|
|
249
|
+
|
|
238
250
|
const requireExt = (X, name) =>
|
|
239
251
|
new Promise((resolve) => X.require(name, (err, ext) => resolve(err ? null : ext)));
|
|
240
252
|
|
|
@@ -266,14 +278,29 @@ export function glCapabilities(app) {
|
|
|
266
278
|
if (policy.mode === 'off') {
|
|
267
279
|
return fail(GLError.DISABLED, "glPolicy is 'off', so no GL context will be created");
|
|
268
280
|
}
|
|
269
|
-
if (!
|
|
281
|
+
if (!app.display.isLocalSocket) {
|
|
270
282
|
return fail(
|
|
271
283
|
GLError.REMOTE_DISPLAY,
|
|
272
|
-
'this X connection is not a local socket
|
|
284
|
+
'this X connection is not a local socket, and DRI3 works by passing a descriptor down one',
|
|
273
285
|
'Direct rendering is local-only by construction. Over a network, indirect GLX is\n' +
|
|
274
286
|
'the backend that can work at all — leave glPolicy at its default.'
|
|
275
287
|
);
|
|
276
288
|
}
|
|
289
|
+
if (!canPassDescriptors(app.display)) {
|
|
290
|
+
// The socket is local; what is missing is the ability to send a
|
|
291
|
+
// descriptor along it. x11 does that through Node's internal
|
|
292
|
+
// `process.binding('pipe_wrap')`, so a runtime that does not implement
|
|
293
|
+
// it lands here — Bun, today. Saying "not a local socket" would send
|
|
294
|
+
// the reader off to check their DISPLAY, which is fine.
|
|
295
|
+
return fail(
|
|
296
|
+
GLError.NO_FD_PASSING,
|
|
297
|
+
`this ${runtimeName()} cannot pass file descriptors over the X socket, and DRI3 works by passing one`,
|
|
298
|
+
'The connection is local; the runtime is what cannot carry the descriptor.\n' +
|
|
299
|
+
"x11 sends one through Node's process.binding('pipe_wrap'), which Bun does\n" +
|
|
300
|
+
'not implement. Run under Node for direct rendering, or leave glPolicy at its\n' +
|
|
301
|
+
'default and use indirect GLX, which needs no descriptor passing at all.'
|
|
302
|
+
);
|
|
303
|
+
}
|
|
277
304
|
|
|
278
305
|
const client = probeDirect(policy);
|
|
279
306
|
if (!client.ok) return fail(client.code, client.message, client.hint);
|
|
@@ -291,9 +318,10 @@ export function glCapabilities(app) {
|
|
|
291
318
|
}
|
|
292
319
|
if (!DRI3.fdCapable) {
|
|
293
320
|
return fail(
|
|
294
|
-
GLError.
|
|
321
|
+
GLError.NO_FD_PASSING,
|
|
295
322
|
'the x11 client cannot send descriptors on this connection (DRI3.fdCapable is false)',
|
|
296
|
-
'x11 builds an fd-capable socket for local displays unless `shm: false` was passed\
|
|
323
|
+
'x11 builds an fd-capable socket for local displays unless `shm: false` was passed\n' +
|
|
324
|
+
'to createClient, and needs a runtime that can pass descriptors — see above.'
|
|
297
325
|
);
|
|
298
326
|
}
|
|
299
327
|
|
|
@@ -2965,15 +2965,21 @@ class RenderingContext2d {
|
|
|
2965
2965
|
rect.h,
|
|
2966
2966
|
]);
|
|
2967
2967
|
}
|
|
2968
|
+
// The scratch mask is surface-sized and surface-aligned — the coverage
|
|
2969
|
+
// went into it at (dx, dy) — and so is a gradient source, so both are
|
|
2970
|
+
// sampled at the destination offset. Reading either from (0, 0) draws a
|
|
2971
|
+
// dw x dh window out of the wrong part of a full-surface picture: for
|
|
2972
|
+
// the mask that is the region just cleared to zero, so nothing paints at
|
|
2973
|
+
// all unless dx and dy are both zero.
|
|
2968
2974
|
R.Composite(
|
|
2969
2975
|
op,
|
|
2970
2976
|
this._backgroundPicture.id,
|
|
2971
2977
|
this.fillMask.id,
|
|
2972
2978
|
this.picture.id,
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2979
|
+
dx,
|
|
2980
|
+
dy,
|
|
2981
|
+
dx,
|
|
2982
|
+
dy,
|
|
2977
2983
|
dx,
|
|
2978
2984
|
dy,
|
|
2979
2985
|
dw,
|
|
@@ -2996,13 +3002,16 @@ class RenderingContext2d {
|
|
|
2996
3002
|
rect.h,
|
|
2997
3003
|
]);
|
|
2998
3004
|
}
|
|
3005
|
+
// the source is a 1x1 repeating solid (offset irrelevant) or the fill
|
|
3006
|
+
// picture, which for a gradient is surface-aligned: same offset as the
|
|
3007
|
+
// destination, exactly as in _fillPolys
|
|
2999
3008
|
R.Composite(
|
|
3000
3009
|
op,
|
|
3001
3010
|
this._coverageSource().id,
|
|
3002
3011
|
picture.id,
|
|
3003
3012
|
this.picture.id,
|
|
3004
|
-
|
|
3005
|
-
|
|
3013
|
+
dx,
|
|
3014
|
+
dy,
|
|
3006
3015
|
mx,
|
|
3007
3016
|
my,
|
|
3008
3017
|
dx,
|