@@ -5,87 +5,89 @@ const childArg = '--child';
55
66const probes = [
77 {
8- name : 'GlfwWindow Cocoa hidden default' ,
8+ name : 'glfw/cocoa/ default' ,
99 kind : 'glfw' ,
1010 platform : 'cocoa' ,
1111 window : 'hidden' ,
1212 } ,
1313 {
14- name : 'GlfwWindow Cocoa hidden no depth/stencil ' ,
14+ name : 'glfw/cocoa/loose ' ,
1515 kind : 'glfw' ,
1616 platform : 'cocoa' ,
1717 window : 'loose' ,
1818 } ,
1919 {
20- name : 'GlfwWindow Cocoa hidden dont-care framebuffer ' ,
20+ name : 'glfw/cocoa/ dont-care' ,
2121 kind : 'glfw' ,
2222 platform : 'cocoa' ,
2323 window : 'dont-care' ,
2424 } ,
2525 {
26- name : 'GlfwWindow Cocoa hidden core profile ' ,
26+ name : 'glfw/cocoa/ core' ,
2727 kind : 'glfw' ,
2828 platform : 'cocoa' ,
2929 window : 'core-profile' ,
3030 } ,
3131 {
32- name : 'GlfwWindow Null hidden default' ,
32+ name : 'glfw/null/ default' ,
3333 kind : 'glfw' ,
3434 platform : 'null' ,
3535 window : 'hidden' ,
3636 } ,
3737 {
38- name : 'GlfwWindow Null OSMesa hidden ' ,
38+ name : 'glfw/null/osmesa ' ,
3939 kind : 'glfw' ,
4040 platform : 'null' ,
4141 window : 'osmesa' ,
4242 } ,
4343 {
44- name : 'GlfwWindow Null EGL hidden ' ,
44+ name : 'glfw/null/egl ' ,
4545 kind : 'glfw' ,
4646 platform : 'null' ,
4747 window : 'egl' ,
4848 } ,
4949 {
50- name : 'BrowserDocument Cocoa hidden no depth/stencil ' ,
50+ name : 'doc/cocoa/loose ' ,
5151 kind : 'document' ,
5252 platform : 'cocoa' ,
5353 window : 'loose' ,
5454 } ,
5555 {
56- name : 'BrowserDocument Null OSMesa hidden ' ,
56+ name : 'doc/null/osmesa ' ,
5757 kind : 'document' ,
5858 platform : 'null' ,
5959 window : 'osmesa' ,
6060 } ,
6161 {
62- name : 'BrowserDocument Null EGL hidden ' ,
62+ name : 'doc/null/egl ' ,
6363 kind : 'document' ,
6464 platform : 'null' ,
6565 window : 'egl' ,
6666 } ,
6767 {
68- name : 'Core init Cocoa hidden no depth/stencil ' ,
68+ name : 'core/cocoa/loose ' ,
6969 kind : 'core' ,
7070 platform : 'cocoa' ,
7171 window : 'loose' ,
7272 } ,
7373 {
74- name : 'Core init Null OSMesa hidden ' ,
74+ name : 'core/null/osmesa ' ,
7575 kind : 'core' ,
7676 platform : 'null' ,
7777 window : 'osmesa' ,
7878 } ,
7979 {
80- name : 'Core init Null EGL hidden ' ,
80+ name : 'core/null/egl ' ,
8181 kind : 'core' ,
8282 platform : 'null' ,
8383 window : 'egl' ,
8484 } ,
8585] ;
8686
87+ const reportPrefix = '__NODE_3D_GL_PROBE__' ;
88+
8789const log = ( ...args ) => {
88- console . log ( '[macos-gl-probe ]' , ...args ) ;
90+ console . log ( '[gl ]' , ...args ) ;
8991} ;
9092
9193const asMessage = ( error ) => {
@@ -97,21 +99,63 @@ const asMessage = (error) => {
9799
98100const boolFromExitCode = ( code ) => code === 0 ;
99101
102+ const uniq = ( values ) => [ ...new Set ( values ) ] ;
103+
104+ const extractGlfwErrors = ( output ) =>
105+ uniq (
106+ output
107+ . split ( / \r ? \n / u)
108+ . map ( ( line ) => line . trim ( ) )
109+ . filter ( ( line ) => line . startsWith ( 'GLFW Error ' ) ) ,
110+ ) ;
111+
112+ const readChildReport = ( stdout ) => {
113+ const line = stdout
114+ . split ( / \r ? \n / u)
115+ . find ( ( currentLine ) => currentLine . startsWith ( reportPrefix ) ) ;
116+
117+ if ( ! line ) {
118+ return null ;
119+ }
120+
121+ return JSON . parse ( line . slice ( reportPrefix . length ) ) ;
122+ } ;
123+
124+ const envText = ( ) => {
125+ const dyld = process . env [ 'DYLD_LIBRARY_PATH' ] || '<unset>' ;
126+ const fallback = process . env [ 'DYLD_FALLBACK_LIBRARY_PATH' ] || '<unset>' ;
127+ const software = process . env [ 'LIBGL_ALWAYS_SOFTWARE' ] || '<unset>' ;
128+ const driver = process . env [ 'MESA_LOADER_DRIVER_OVERRIDE' ] || '<unset>' ;
129+ return `dyld=${ dyld } fallback=${ fallback } software=${ software } driver=${ driver } ` ;
130+ } ;
131+
100132const runParent = ( ) => {
101- log ( 'parent node' , process . version , process . platform , process . arch ) ;
133+ log ( 'node' , process . version , process . platform , process . arch ) ;
134+ log ( 'env' , envText ( ) ) ;
102135
103136 const results = probes . map ( ( probe ) => {
104- log ( `child start: ${ probe . name } ` ) ;
105137 const child = spawnSync ( process . execPath , [ import . meta. filename , childArg ] , {
138+ encoding : 'utf8' ,
106139 env : {
107140 ...process . env ,
108141 NODE_3D_MACOS_GL_PROBE : JSON . stringify ( probe ) ,
109142 } ,
110- stdio : 'inherit' ,
111143 } ) ;
112144
113145 const isOk = boolFromExitCode ( child . status ) ;
114- log ( `child ${ isOk ? 'ok' : 'failed' } : ${ probe . name } ` ) ;
146+ const stdout = child . stdout || '' ;
147+ const stderr = child . stderr || '' ;
148+ const report = readChildReport ( stdout ) ;
149+ const glfwErrors = extractGlfwErrors ( `${ stdout } \n${ stderr } ` ) ;
150+
151+ if ( isOk && report ?. ok ) {
152+ log ( `ok ${ probe . name } : version=${ report . version } fb=${ report . framebufferSize } ` ) ;
153+ } else {
154+ const error = report ?. error || child . error ?. message || `exit ${ child . status } ` ;
155+ const glfwText = glfwErrors . length > 0 ? `; ${ glfwErrors . join ( ' | ' ) } ` : '' ;
156+ log ( `fail ${ probe . name } : ${ error } ${ glfwText } ` ) ;
157+ }
158+
115159 return isOk ;
116160 } ) ;
117161
@@ -129,29 +173,8 @@ const readProbe = () => {
129173 return JSON . parse ( value ) ;
130174} ;
131175
132- const describeGlfw = ( glfw ) => {
133- log ( 'node' , process . version , process . platform , process . arch ) ;
134- log ( 'glfw version' , glfw . getVersionString ?. ( ) ) ;
135- log ( 'glfw windowHint' , typeof glfw . windowHint ) ;
136- log ( 'glfw initHint' , typeof glfw . initHint ) ;
137- log ( 'glfw createWindow' , typeof glfw . createWindow ) ;
138- log ( 'glfw PLATFORM' , glfw . PLATFORM ) ;
139- log ( 'glfw PLATFORM_COCOA' , glfw . PLATFORM_COCOA ) ;
140- log ( 'glfw PLATFORM_NULL' , glfw . PLATFORM_NULL ) ;
141- log ( 'glfw CONTEXT_CREATION_API' , glfw . CONTEXT_CREATION_API ) ;
142- log ( 'glfw NATIVE_CONTEXT_API' , glfw . NATIVE_CONTEXT_API ) ;
143- log ( 'glfw EGL_CONTEXT_API' , glfw . EGL_CONTEXT_API ) ;
144- log ( 'glfw OSMESA_CONTEXT_API' , glfw . OSMESA_CONTEXT_API ) ;
145- log ( 'glfw STENCIL_BITS' , glfw . STENCIL_BITS ) ;
146- log ( 'glfw DEPTH_BITS' , glfw . DEPTH_BITS ) ;
147- log ( 'glfw SAMPLES' , glfw . SAMPLES ) ;
148- log ( 'glfw DONT_CARE' , glfw . DONT_CARE ) ;
149- log ( 'DYLD_LIBRARY_PATH' , process . env [ 'DYLD_LIBRARY_PATH' ] ) ;
150- log ( 'DYLD_FALLBACK_LIBRARY_PATH' , process . env [ 'DYLD_FALLBACK_LIBRARY_PATH' ] ) ;
151- log ( 'LIBGL_ALWAYS_SOFTWARE' , process . env [ 'LIBGL_ALWAYS_SOFTWARE' ] ) ;
152- log ( 'MESA_LOADER_DRIVER_OVERRIDE' , process . env [ 'MESA_LOADER_DRIVER_OVERRIDE' ] ) ;
153- log ( 'glfw property names' , Object . getOwnPropertyNames ( glfw ) . length ) ;
154- log ( 'glfw enumerable keys' , Object . keys ( glfw ) . length ) ;
176+ const writeReport = ( report ) => {
177+ console . log ( `${ reportPrefix } ${ JSON . stringify ( report ) } ` ) ;
155178} ;
156179
157180const setInitHints = ( glfw , probe ) => {
@@ -214,21 +237,14 @@ const makeBeforeWindow = (windowKind) => (_window, currentGlfw) => {
214237 setWindowHints ( currentGlfw , windowKind ) ;
215238} ;
216239
217- const destroy = ( window ) => {
240+ const destroy = ( window , logger = log ) => {
218241 try {
219242 window ?. destroy ( ) ;
220243 } catch ( error ) {
221- log ( 'destroy failed' , asMessage ( error ) ) ;
244+ logger ( 'destroy failed' , asMessage ( error ) ) ;
222245 }
223246} ;
224247
225- const printWindow = ( window ) => {
226- log ( 'window version' , window . version ) ;
227- log ( 'window size' , JSON . stringify ( window . size ) ) ;
228- log ( 'framebuffer size' , JSON . stringify ( window . framebufferSize ) ) ;
229- log ( 'platform context' , window . platformContext ) ;
230- } ;
231-
232248const runChild = async ( ) => {
233249 const probe = readProbe ( ) ;
234250
@@ -237,8 +253,6 @@ const runChild = async () => {
237253 globalThis [ '__isGlfwInited' ] = true ;
238254
239255 const { GlfwWindow, glfw } = await import ( '@node-3d/glfw' ) ;
240- describeGlfw ( glfw ) ;
241- log ( `probe start: ${ probe . name } ` ) ;
242256 initGlfw ( glfw , probe ) ;
243257
244258 let window = null ;
@@ -273,14 +287,22 @@ const runChild = async () => {
273287 throw new Error ( `Unknown probe kind: ${ probe . kind } ` ) ;
274288 }
275289
276- log ( `probe ok: ${ probe . name } ` ) ;
277- printWindow ( window ) ;
290+ writeReport ( {
291+ ok : true ,
292+ name : probe . name ,
293+ version : window . version ,
294+ framebufferSize : window . framebufferSize ,
295+ platformContext : window . platformContext ,
296+ } ) ;
278297 } catch ( error ) {
279- log ( `probe failed: ${ probe . name } ` ) ;
280- log ( asMessage ( error ) ) ;
298+ writeReport ( {
299+ ok : false ,
300+ name : probe . name ,
301+ error : asMessage ( error ) ,
302+ } ) ;
281303 process . exitCode = 1 ;
282304 } finally {
283- destroy ( window ) ;
305+ destroy ( window , ( ) => null ) ;
284306 glfw . terminate ( ) ;
285307 }
286308} ;
0 commit comments